<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Chanuka Dinuwan</title>
    <description>The latest articles on Forem by Chanuka Dinuwan (@chanuka).</description>
    <link>https://forem.com/chanuka</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1715281%2F9fce42a8-1ce4-4ccc-8d58-1ff94f7d8bc6.jpeg</url>
      <title>Forem: Chanuka Dinuwan</title>
      <link>https://forem.com/chanuka</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/chanuka"/>
    <language>en</language>
    <item>
      <title>Building a GraphQL API with Spring Boot: A Complete Guide</title>
      <dc:creator>Chanuka Dinuwan</dc:creator>
      <pubDate>Fri, 23 May 2025 19:17:45 +0000</pubDate>
      <link>https://forem.com/chanuka/building-a-graphql-api-with-spring-boot-a-complete-guide-2no3</link>
      <guid>https://forem.com/chanuka/building-a-graphql-api-with-spring-boot-a-complete-guide-2no3</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft78dswo3c4ydjjyra1bn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft78dswo3c4ydjjyra1bn.png" alt=" " width="720" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In modern API development, Eve``ryone focuses on flexibility and efficiency. Traditional REST APIs often lead to over- or under-fetching of data, especially in complex systems with deeply nested relationships. Graphql, a query language developed by Facebook, addresses these issues by allowing clients to request the exact data they need.&lt;/p&gt;

&lt;p&gt;When combined with Spring Boot, a powerful Java-based framework for building Microservices, GraphQL becomes a robust solution for building flexible, scalable APIs. This blog discusses how to integrate GraphQL with Spring Boot, allowing you to build APIs that are not only performant and type-safe but also developer-friendly and adaptable to changing client requirements.&lt;/p&gt;

&lt;p&gt;GraphQL Documentation: &lt;a href="https://graphql.org" rel="noopener noreferrer"&gt;https://graphql.org&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GraphQL with Spring Boot Documentation: &lt;a href="https://spring.io/guides/gs/graphql-server" rel="noopener noreferrer"&gt;https://spring.io/guides/gs/graphql-server&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  GraphQL vs Rest
&lt;/h2&gt;

&lt;p&gt;Rest has been the standard architectural style for building APIs for years now, GraphQL offers a modern alternative designed for flexibility and efficiency in data retrieval. The table below summarizes the key differences between the two approaches:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2tbm21id8uo4uvag654.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2tbm21id8uo4uvag654.png" alt=" " width="784" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up Spring Boot Application
&lt;/h2&gt;

&lt;p&gt;We need to use a GraphQL maven or gradle dependency to implement the Spring boot application with GraphQL.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;`&lt;br&gt;
&amp;lt;dependency&amp;gt;&lt;br&gt;
  &amp;lt;groupId&amp;gt;org.springframework.graphql&amp;lt;/groupId&amp;gt;&lt;br&gt;
  &amp;lt;artifactId&amp;gt;spring-graphql-test&amp;lt;/artifactId&amp;gt;&lt;br&gt;
  &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;&lt;br&gt;
&amp;lt;/dependency&amp;gt;&lt;br&gt;
`&lt;/code&gt;&lt;br&gt;
We need to create a simple Spring Boot application to try this or you can clone it here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/cdin8619-0/graphql-springboot.git" rel="noopener noreferrer"&gt;https://github.com/cdin8619-0/graphql-springboot.git&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;

&lt;p&gt;Let’s dive into the main component of our application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entity classes&lt;/li&gt;
&lt;li&gt;Repository interfaces&lt;/li&gt;
&lt;li&gt;Service classes&lt;/li&gt;
&lt;li&gt;Controllers with GraphQL annotations&lt;/li&gt;
&lt;li&gt;GraphQL schema definition&lt;/li&gt;
&lt;li&gt;Controller implementation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Controller implementation
&lt;/h2&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;br&gt;
@Controller&lt;br&gt;
public class ProductController {&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private ProductService productService;

@Autowired
public ProductController(ProductService productService) {
    this.productService = productService;
}

@QueryMapping
public List&amp;lt;Product&amp;gt; getProducts() {
    return productService.getAllProducts();
}

@QueryMapping
public List&amp;lt;Product&amp;gt; getProductsByCategory(@PathVariable String category) {
    return productService.getProductsByCategory(category);
}

@MutationMapping
public Product updateStock(@Argument int productId, @Argument int stock) {
    return productService.updateStock(productId, stock);
}

@MutationMapping
public Product receiveNewShipment(@Argument int productId, @Argument int quantity) {
    return productService.receiveNewShipment(productId, quantity);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
&lt;code&gt;&lt;/code&gt;`&lt;/p&gt;

&lt;p&gt;The @QueryMapping and @MutationMapping annotations in Spring for GraphQL simplify linking methods to GraphQL query and mutation fields. They are concise alternatives to @SchemaMapping:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;@QueryMapping: Maps a method to a GraphQL query field, typically using the method name.&lt;/li&gt;
&lt;li&gt;@MutationMapping: Maps a method to a GraphQL mutation field for handling data changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Service Implementation
&lt;/h2&gt;

&lt;p&gt;This is the place where we write logic. This is the same as the normal Spring Boot applications.&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;br&gt;
@Service&lt;br&gt;
public class ProductService {&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Autowired
private ProductRepository productRepository;

public List&amp;lt;Product&amp;gt; getAllProducts() {
    return productRepository.findAll();
}

public List&amp;lt;Product&amp;gt; getProductsByCategory(String category) {
    return productRepository.findByCategory(category);
}

public Product updateStock(int id , int stock) {
    Product existingProduct = productRepository.findById(id).orElseThrow(() -&amp;gt; new RuntimeException("Product not found"));

    existingProduct.setStock(stock);
    return productRepository.save(existingProduct);
}

public Product receiveNewShipment(int id , int quantity) {
    Product existingProduct = productRepository.findById(id).orElseThrow(() -&amp;gt; new RuntimeException("Product not found"));

    existingProduct.setStock(existingProduct.getStock() + quantity);
    return productRepository.save(existingProduct);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
&lt;code&gt;&lt;/code&gt;`&lt;/p&gt;

&lt;h2&gt;
  
  
  GraphQL Schema Definition
&lt;/h2&gt;

&lt;p&gt;Our application needs to define the schema that describes our data model and operations. Create a file named schema.graphqls in the src/main/resources/graphql directory:&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;br&gt;
type Product {&lt;br&gt;
    id: ID,&lt;br&gt;
    name: String,&lt;br&gt;
    category: String,&lt;br&gt;
    price: Float,&lt;br&gt;
    stock: Int&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;type Query {&lt;br&gt;
    getProducts: [Product]&lt;br&gt;
    getProductsByCategory(category: String): [Product]&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;type Mutation {&lt;br&gt;
    updateStock(productId: ID, stock: Int): Product&lt;br&gt;
    receiveNewShipment(productId: ID, quantity: Int): Product&lt;br&gt;
}&lt;br&gt;
&lt;code&gt;&lt;/code&gt;`&lt;/p&gt;

&lt;h2&gt;
  
  
  Entity Class and Repository Implementation
&lt;/h2&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;br&gt;
@Entity&lt;br&gt;
&lt;a class="mentioned-user" href="https://dev.to/data"&gt;@data&lt;/a&gt;&lt;br&gt;
@NoArgsConstructor&lt;br&gt;
@AllArgsConstructor&lt;br&gt;
public class Product {&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

private String name;
private String category;
private float price;
private int stock;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
&lt;code&gt;&lt;/code&gt;`&lt;/p&gt;

&lt;p&gt;&lt;code&gt;`&lt;br&gt;
@Repository&lt;br&gt;
public interface ProductRepository extends JpaRepository&amp;lt;Product, Integer&amp;gt; {&lt;br&gt;
    List&amp;lt;Product&amp;gt; findByCategory(String category);&lt;br&gt;
}&lt;br&gt;
`&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I created a data loader class to load initial data to the application.&lt;/p&gt;

&lt;p&gt;Add the following properties to application.properties(or application.yml):&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;br&gt;
spring.application.name=graphql-springboot&lt;br&gt;
server.port=9090&lt;/p&gt;

&lt;h1&gt;
  
  
  Database configuration
&lt;/h1&gt;

&lt;p&gt;spring.datasource.url=jdbc:h2:mem:productdb&lt;br&gt;
spring.datasource.driverClassName=org.h2.Driver&lt;br&gt;
spring.datasource.username=sa&lt;br&gt;
spring.datasource.password=&lt;br&gt;
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect&lt;br&gt;
spring.h2.console.enabled=true&lt;br&gt;
spring.datasource.auto-create=true&lt;/p&gt;

&lt;h1&gt;
  
  
  GraphQL endpoint path (default is /graphql)
&lt;/h1&gt;

&lt;p&gt;spring.graphql.path=/graphql&lt;/p&gt;

&lt;h1&gt;
  
  
  Enable GraphiQL
&lt;/h1&gt;

&lt;p&gt;spring.graphql.graphiql.enabled=true&lt;br&gt;
spring.graphql.graphiql.path=/graphiql&lt;br&gt;
&lt;code&gt;&lt;/code&gt;`&lt;/p&gt;

&lt;p&gt;Database configuration may be different for yours than mine. But add the above-mentioned GraphQL configurations to your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing with GraphiQL
&lt;/h2&gt;

&lt;p&gt;Spring Boot with GraphQL provides an integrated GraphiQL interface for testing GraphQL queries. After running the application, navigate to &lt;a href="http://localhost:8080/graphiql" rel="noopener noreferrer"&gt;http://localhost:8080/graphiql&lt;/a&gt; to interact with your API. There you can play with application GraphQL APIs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9hxk7mkmygajgmlpxb00.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9hxk7mkmygajgmlpxb00.png" alt=" " width="720" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are some sample queries and mutations:&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;br&gt;
Get All Products&lt;br&gt;
graphqlquery {&lt;br&gt;
  getProducts {&lt;br&gt;
    id&lt;br&gt;
    name&lt;br&gt;
    category&lt;br&gt;
    price&lt;br&gt;
    stock&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Get Products by Category&lt;br&gt;
graphqlquery {&lt;br&gt;
  getProductsByCategory(category: "Electronics") {&lt;br&gt;
    id&lt;br&gt;
    name&lt;br&gt;
    price&lt;br&gt;
    stock&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Update Product Stock&lt;br&gt;
graphqlmutation {&lt;br&gt;
  updateStock(productId: 1, stock: 25) {&lt;br&gt;
    id&lt;br&gt;
    name&lt;br&gt;
    category&lt;br&gt;
    stock&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Receive New Shipment&lt;br&gt;
graphqlmutation {&lt;br&gt;
  receiveNewShipment(productId: 2, quantity: 10) {&lt;br&gt;
    id&lt;br&gt;
    name&lt;br&gt;
    category&lt;br&gt;
    stock&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
&lt;code&gt;&lt;/code&gt;`&lt;/p&gt;

&lt;p&gt;You can also use a Postman or a similar tool to test your GraphQL application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjnyk0m3nbqh5qtey89pw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjnyk0m3nbqh5qtey89pw.png" alt=" " width="720" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Error Handing in GraphQL
&lt;/h2&gt;

&lt;p&gt;GraphQL has a different approach to error handling compared to REST. Let’s enhance our application with proper error handling.&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;br&gt;
package com.example.graphqlspringboot.exception;&lt;/p&gt;

&lt;p&gt;import graphql.GraphQLError;&lt;br&gt;
import graphql.GraphqlErrorBuilder;&lt;br&gt;
import graphql.schema.DataFetchingEnvironment;&lt;br&gt;
import org.springframework.graphql.execution.DataFetcherExceptionResolverAdapter;&lt;br&gt;
import org.springframework.stereotype.Component;&lt;/p&gt;

&lt;p&gt;@Component&lt;br&gt;
public class GraphQLExceptionHandler extends DataFetcherExceptionResolverAdapter {&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Override
protected GraphQLError resolveToSingleError(Throwable ex, DataFetchingEnvironment env) {
    return GraphqlErrorBuilder.newError()
            .message(ex.getMessage())
            .path(env.getExecutionStepInfo().getPath())
            .location(env.getField().getSourceLocation())
            .build();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
&lt;code&gt;&lt;/code&gt;`&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced Features
&lt;/h2&gt;

&lt;h2&gt;
  
  
  DataLoaders for Batch Loading
&lt;/h2&gt;

&lt;p&gt;You might face the “N+1 queries” problem when dealing with complex data relationships. GraphQL DataLoaders help solve this issue by batching and caching requests:&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;br&gt;
@Component&lt;br&gt;
public class ProductDataLoader {&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private final ProductRepository productRepository;

public ProductDataLoader(ProductRepository productRepository) {
    this.productRepository = productRepository;
}

@SchemaMapping(typeName = "Query", field = "productsByIds")
public List&amp;lt;Product&amp;gt; getProductsByIds(@Argument List&amp;lt;Integer&amp;gt; ids) {
    return productRepository.findAllById(ids);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
&lt;code&gt;&lt;/code&gt;`&lt;/p&gt;

&lt;h2&gt;
  
  
  Subscriptions for Real-time Update
&lt;/h2&gt;

&lt;p&gt;GraphQL also supports subscriptions for real-time updates. Let’s add a simple stock level subscription:&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;// In GraphQL schema&lt;br&gt;
type Subscription {&lt;br&gt;
    stockLevelChanged: Product&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// In Java code&lt;br&gt;
@SubscriptionMapping&lt;br&gt;
public Publisher stockLevelChanged() {&lt;br&gt;
    return productPublisher;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Considerations
&lt;/h2&gt;

&lt;p&gt;When implementing GraphQL APIs, consider these security aspects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Query Complexity Analysis: Prevent resource-exhausting queries&lt;/li&gt;
&lt;li&gt;Rate Limiting: Control the frequency of requests&lt;/li&gt;
&lt;li&gt;Authentication and Authorization: Protect sensitive operations&lt;/li&gt;
&lt;li&gt;Input Validation: Validate all client inputs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Performance Optimization
&lt;/h2&gt;

&lt;p&gt;For optimal GraphQL performance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Query Depth Limiting: Prevent deeply nested queries&lt;/li&gt;
&lt;li&gt;Result Size Limiting: Control response payload sizes&lt;/li&gt;
&lt;li&gt;Caching: Implement response caching&lt;/li&gt;
&lt;li&gt;Pagination: Use cursor-based pagination for large result sets&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;GraphQL with Spring Boot offers a powerful alternative to traditional REST APIs, providing clients with the flexibility to request exactly the data they need. The strong typing, self-documenting nature, and single endpoint approach make it an excellent choice for modern applications with complex data requirements.&lt;/p&gt;

&lt;p&gt;By implementing GraphQL in your Spring Boot applications, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduce over-fetching and under-fetching of data&lt;/li&gt;
&lt;li&gt;Create better developer experiences with strong typing and tooling&lt;/li&gt;
&lt;li&gt;Enable clients to evolve independently of the server&lt;/li&gt;
&lt;li&gt;Simplify API versioning&lt;/li&gt;
&lt;li&gt;Build more responsive and efficient applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The example provided in this article demonstrates basic GraphQL concepts with Spring Boot, but you can extend it with more complex features like relationships between entities, pagination, filtering, and advanced security measures.&lt;/p&gt;

&lt;p&gt;Remember that GraphQL is not a replacement for REST in all cases — choose the approach that best fits your specific application requirements and constraints.&lt;/p&gt;

&lt;p&gt;Happy coding!🚀&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>java</category>
      <category>graphql</category>
      <category>springboot</category>
    </item>
    <item>
      <title>Organize Your Cloud Environment with AWS My Applications</title>
      <dc:creator>Chanuka Dinuwan</dc:creator>
      <pubDate>Mon, 21 Apr 2025 12:38:26 +0000</pubDate>
      <link>https://forem.com/aws-builders/organize-your-cloud-environment-with-aws-my-applications-25ge</link>
      <guid>https://forem.com/aws-builders/organize-your-cloud-environment-with-aws-my-applications-25ge</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvslofy9nyfj9mp3q4q7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvslofy9nyfj9mp3q4q7.png" alt=" " width="720" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My application is a feature that helps organize and manage resources in the AWS cloud. In the AWS console, we can view my application widget as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2r7fv3osocx4vcvm3a0w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2r7fv3osocx4vcvm3a0w.png" alt=" " width="720" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Below is a summary of the features provided by My Applications:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Organising Resources: Let’s say you’re developing an application that utilises various AWS services, including SQS queues, EC2 instances, and DynamoDB databases. This collaborative effort paves the way for a more convenient method to view all the information of a particular application by using My Applications instead of managing each system separately.&lt;/li&gt;
&lt;li&gt;Centralised Examine: My Application maintains a centralised facade that allows users to look up all the application-related resources they need without the hassle of browsing through all the AWS services to select those they require. Additionally, this will reduce waiting times, enabling quicker and easier document processing.&lt;/li&gt;
&lt;li&gt;Simplified Management: The My Apps feature ensures minimal effort is involved in adding resources to existing applications or creating new applications from scratch. You can also apply tags to sort filters and resources, which simplifies managing permissions across the application.&lt;/li&gt;
&lt;li&gt;Improved Organisation: The introduMygement program introduces more regulation to your cloud, making it easier to manage resources based on function, project, or any other desired attribute. This results in simpler and more organiZed cloud management.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's go through the demo on how to create AWS my application using the AWS console.&lt;/p&gt;

&lt;p&gt;When you click the “Create application” button in the widget, you will be redirected to this page where you can provide the application name and description. If you want to add a unique tag from yourself, you can do that as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvbk0b1x7bkrys2yvhype.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvbk0b1x7bkrys2yvhype.png" alt=" " width="720" height="650"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we click the next button this will redirect us to the page where we can add existing resources to our application. This part is optional if you want to create a new application using existing resources you can use this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8r37evtugbt2ildprxnq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8r37evtugbt2ildprxnq.png" alt=" " width="720" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To use this, you need to enable AWS Resources Explorer. It is a free service. I’m now going to use existing resources to create an application. So, I clicked the “Select Resources” button. Then, it will display a window like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5tug43r757xcnsvltuoc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5tug43r757xcnsvltuoc.png" alt=" " width="720" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I added those resources to my application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmnv717k9uewaw50kza6m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmnv717k9uewaw50kza6m.png" alt=" " width="720" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then let's create the application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9hgzrfexlg611coaa38y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9hgzrfexlg611coaa38y.png" alt=" " width="720" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, here you can see the application named demo in my application widget:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdn7gzosbsxd5an7ytw19.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdn7gzosbsxd5an7ytw19.png" alt=" " width="720" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once we click that you can see the cost for the application, resource consumption, security, monitoring and many more application-wise. And also, you can customise your dashboard, customise it we can set specific alerts too.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffwxfrjs1ct7v4m4e0i1i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffwxfrjs1ct7v4m4e0i1i.png" alt=" " width="720" height="1497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What You Can Do With My Applications:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get the data on the application charges, throughput, security, and monitoring.&lt;/li&gt;
&lt;li&gt;Make your dashboard personalised and for user-friendly access to the data that you need to see instantly.&lt;/li&gt;
&lt;li&gt;Create cloud resource management alerts based on the specific application. Scan the utilization regularly for timely action.&lt;/li&gt;
&lt;li&gt;Using My Apps, you will enjoy greater organization, control, and visibility.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy Coding 🚀!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>cloudcomputing</category>
      <category>devops</category>
    </item>
    <item>
      <title>What I learned from Vibe Coding</title>
      <dc:creator>Chanuka Dinuwan</dc:creator>
      <pubDate>Fri, 18 Apr 2025 18:37:57 +0000</pubDate>
      <link>https://forem.com/chanuka/what-i-learned-from-vibe-coding-cbb</link>
      <guid>https://forem.com/chanuka/what-i-learned-from-vibe-coding-cbb</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwb56ag403bqcreonbjmm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwb56ag403bqcreonbjmm.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Software development is changing rapidly, and a new way of coding is becoming popular. It’s called “vibe coding,” a term used by Andrej Karpathy. This isn’t about how code appears or feels. It’s about leveraging AI to handle the majority of the heavy lifting in code writing. Developers who use AI can complete 26% more work, and they’re able to finish coding tasks 55% faster, and 81% agree that productivity is their biggest benefit. Even if you’ve given AI a try in the past, the technologies are changing weekly with new models, beating the best developers in coding competitions. This new generation of models can understand the context of your entire code base, debugging, commenting, and refactoring code for you. They can help you as an AI pair programmer, and eliminate the need to look up solutions online.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3e9kqij8om41394cffgu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3e9kqij8om41394cffgu.png" alt=" " width="800" height="556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the Vibe Coding?
&lt;/h2&gt;

&lt;p&gt;Karpathy describes vibe coding as “Giving into vibes, embrace exponentials, and forget that code even exists” At its core vibe coding means working with AI coding assistant and adopting an “accept all” philosophy- assuming the AI will write and fix the software you’re creating with minimal human intervention.&lt;/p&gt;

&lt;p&gt;Unlike traditional programming approaches that require developers to craft each line of code, vibe coding encourages developers to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Focus on high-level ideas and concepts.&lt;/li&gt;
&lt;li&gt;Let AI generate the implementation details.&lt;/li&gt;
&lt;li&gt;Accept AI suggestions with minimal review or changes.&lt;/li&gt;
&lt;li&gt;Use prompt engineering rather than manual coding.&lt;/li&gt;
&lt;li&gt;Iterate through AI assistance rather than manual debugging.&lt;/li&gt;
&lt;li&gt;This represents a fundamental shift in how we think about the developer’s role-from code writer to code director.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setup Cursor for Vibe Coding
&lt;/h2&gt;

&lt;p&gt;Cursor AI is an AI-powered code editor designed to enhance the coding experience by integrating AI to assist with various tasks, including code completion, code generation, and codebase understanding. It aims to streamline the coding process and improve productivity. You can download it from here: &lt;a href="https://www.cursor.com/downloads" rel="noopener noreferrer"&gt;https://www.cursor.com/downloads&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you download a cursor code editor you need to setup it up. First you need to setup your keybinding, prompting language and other couple of settings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feuz70kue8vbxp1zy0jcu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feuz70kue8vbxp1zy0jcu.png" alt=" " width="800" height="998"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cursor functions more effectively when you grant access to the full code. This allows you to choose how to manage your data. You can either opt for a privacy mode or share your data with Cursor. Within the Cursor settings, you can establish rules for the AI and select the model you wish to use.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffx8llvkm8zohynt21mjk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffx8llvkm8zohynt21mjk.png" alt=" " width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have API keys for LLM models, you can add them to Cursor and access premium features. However, this option is more expensive than purchasing a pro version of Cursor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjgzd2tasmyo7polpyqka.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjgzd2tasmyo7polpyqka.png" alt=" " width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Start Vibe Coding
&lt;/h2&gt;

&lt;p&gt;I found that we need to follow these steps when we vibe coding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Plan project&lt;/li&gt;
&lt;li&gt;Set Guidelines&lt;/li&gt;
&lt;li&gt;Write Prompts&lt;/li&gt;
&lt;li&gt;Review Output&lt;/li&gt;
&lt;li&gt;Iterate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then I started vibe coding using a cursor. Before that, we needed to plan the application. I’m going to implement a ToDo application that contains an Express JS backend and a React frontend. For that, I used this command first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a full-stack ToDo application using React for the frontend and 
Node.js with Express for the backend. Set up two folders: /client for 
frontend and /server for backend. Use TypeScript in both. 
Include an initial README in root with setup instructions.

In /client folder, create a React app using TypeScript and TailwindCSS. 
Build a simple UI for a ToDo app with the following features:
- Input to add a task
- List to display tasks
- Checkbox to mark complete
- Delete button to remove task
Use functional components and hooks. Maintain tasks using local state.


In /server folder, build a Node.js backend using Express and TypeScript. 
Implement RESTful API endpoints for managing todos:
- GET /todos
- POST /todos
- PUT /todos/:id
- DELETE /todos/:id
Use an in-memory array to store todos. Add basic error handling and 
CORS support.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then cursor started to create folders and necessary files for the application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fablptxs0r8i15irgi3lf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fablptxs0r8i15irgi3lf.png" alt=" " width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I accepted all the suggestions commands and code changes that Cursor has given to me.&lt;/p&gt;

&lt;p&gt;Then I gave a prompt to integrate frontend with backend.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Update the frontend in /client to consume the backend API 
from /server. Replace local state with API calls using axios:
- GET to load todos
- POST to create new todo
- PUT to toggle complete
- DELETE to remove todo
Ensure proper async/await and error handling.

Update the frontend in /client to consume the backend API 
from /server. Replace local state with API calls using axios:
- GET to load todos
- POST to create new todo
- PUT to toggle complete
- DELETE to remove todo
Ensure proper async/await and error handling.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then Cursor created me a Todo application. But it had some issues. I gave that as prompt and asked to fix. It fixed issues and finally created a ToDo application. Then I asked Cursor to write unit testing for that application using this prompt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add basic test coverage:
- For backend: use Jest and Supertest to test API endpoints
- For frontend: use React Testing Library to test rendering and 
user interactions
Include at least 1 test per core functionality.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I provided prompts to prepare it for production.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prepare the app for deployment:
- Add production build scripts
- Serve React frontend using Express in production
- Add environment variable support (.env)
- Provide instructions to deploy to Vercel (frontend) and Render 
or Railway (backend)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have noticed that the cursor keeps checkpoints after each prompt. If our prompts go wrong or the application doesn’t work after a new modification, we can simply restore to that checkpoint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv6u86qv0rirxno8i87by.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv6u86qv0rirxno8i87by.png" alt=" " width="630" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I ran the both backend and frontend applications. It worked well. But there were some css issues. But when it comes to functionality, it works really well. Claude 3.7 sonnet performed better than other LLM models.&lt;/p&gt;

&lt;p&gt;This is the final application that I have created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuf68lsmdtwdo90d1lz0q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuf68lsmdtwdo90d1lz0q.png" alt=" " width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can enhance the UI by suggesting colors and others alignments. The best part about this application? I didn’t write a single line of code myself. Everything — from installations to commands — was generated by Cursor AI. I didn’t even touch the codebase; I just accepted all the suggestions the AI provided.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does the future hold with the rise of AI tools?
&lt;/h2&gt;

&lt;p&gt;This is my 2 cents about it:&lt;/p&gt;

&lt;p&gt;AI still developing and it’s not too perfect. So still manual intervention for software development must needed.&lt;/p&gt;

&lt;p&gt;In the future, we may see a merger of roles, such as DevOps engineers and software engineers. Companies will likely expect engineers to be proficient in multiple programming languages, creating a demand for T-shaped engineers.&lt;/p&gt;

&lt;p&gt;Continuous learning and efficient use of these tools will give individuals a competitive edge in this evolving landscape. A deeper understanding of these technologies will aid in this process.&lt;/p&gt;

&lt;p&gt;Happy Coding 🚀!&lt;/p&gt;

</description>
      <category>vibecoding</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Deploying a Spring Boot Application on Kubernetes with AWS EKS</title>
      <dc:creator>Chanuka Dinuwan</dc:creator>
      <pubDate>Sat, 22 Mar 2025 10:41:02 +0000</pubDate>
      <link>https://forem.com/chanuka/deploying-a-spring-boot-application-on-kubernetes-with-aws-eks-3hjm</link>
      <guid>https://forem.com/chanuka/deploying-a-spring-boot-application-on-kubernetes-with-aws-eks-3hjm</guid>
      <description>&lt;p&gt;In this guide, we will explore how to deploy a Spring Boot application to AWS &lt;strong&gt;Elastic Kubernetes Service (EKS)&lt;/strong&gt;. To follow along, you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An AWS account&lt;/li&gt;
&lt;li&gt;AWS CLI installed and configured&lt;/li&gt;
&lt;li&gt;Kubectl (Kubernetes command-line tool)&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;eksctl (for creating EKS clusters)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a Spring Boot application.&lt;/li&gt;
&lt;li&gt;Generate a Dockerfile for the application.&lt;/li&gt;
&lt;li&gt;Push the Docker image to AWS Elastic Container Registry (ECR).&lt;/li&gt;
&lt;li&gt;Deploy the application in AWS EKS.&lt;/li&gt;
&lt;li&gt;Expose the application using a LoadBalancer Service&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Create a Spring Boot application
&lt;/h2&gt;

&lt;p&gt;For this guide, I have created a simple Spring Boot application. You can find the source code here: GitHub Repository&lt;/p&gt;

&lt;h2&gt;
  
  
  Generate a Docker Image from the Spring Boot application
&lt;/h2&gt;

&lt;p&gt;Then, we need to create a Dockerfile for our AWS application. Dockerfile should be like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM openjdk-17
ADD target/springboot-eks-deployment.jar springboot-eks-deployment.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "springboot-eks-deployment.jar"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure your pom.xml  tag is set springboot-eks-deployment so that the JAR file matches the expected name.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker build -t springboot-eks .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl3sh2s6znxtxonx5kw9n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl3sh2s6znxtxonx5kw9n.png" alt=" " width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Push that Dockerfile into AWS ECR
&lt;/h2&gt;

&lt;p&gt;Then, create a repository in ECR.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nvmiulmq106vm8c8ci9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nvmiulmq106vm8c8ci9.png" alt=" " width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, go inside the repository and click the view push commands button. Then you can see a pop-up like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3yfic9sa3d4pxmyfurk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3yfic9sa3d4pxmyfurk.png" alt=" " width="800" height="356"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the first command and paste that into your command line.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 135808938067.dkr.ecr.us-east-1.amazonaws.com&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, tag the image:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker tag springboot-eks:latest 135808938067.dkr.ecr.us-east-1.amazonaws.com/springboot-eks:latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, push the image:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker push 135808938067.dkr.ecr.us-east-1.amazonaws.com/springboot-eks:latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once pushed, keep the image URI for deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pull the Image and Deploy on EKS
&lt;/h2&gt;

&lt;p&gt;Let’s create an EKS cluster.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;eksctl create cluster --name eks-cluster-springboot --version 1.28 --nodes=1 --node-type=t2.small --region us-east-2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Suppose you can’t find any command like this. Please run the following commands to install it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;brew tap weaveworks/tap&lt;br&gt;
brew install weaveworks/tap/eksctl&lt;/code&gt;&lt;br&gt;
Once you enter the command, the CLI looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fww63eyaq1hmts9yqmf3n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fww63eyaq1hmts9yqmf3n.png" alt=" " width="800" height="235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It takes 15–20 minutes to finish the cluster creation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbpyx1cy0hhttwyhv3c3l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbpyx1cy0hhttwyhv3c3l.png" alt=" " width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s add kubeconfig to our machine CLI.&lt;br&gt;
&lt;code&gt;aws eks --region us-east-2 update-kubeconfig --name eks-cluster-springboot&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, create a configuration file for Kubernetes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
        - name: myapp
          image: &amp;lt;your docker image url&amp;gt;
          ports:
            - containerPort: 8080

---
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  selector:
    app: myapp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: LoadBalancer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply it:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl apply -f k8s.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Validate using:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl get svc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can see my-app deployment created in EKS.&lt;/p&gt;

&lt;p&gt;You can see after get svc command URL like this:&lt;/p&gt;

&lt;p&gt;a6a6cb0416fc14d5faa0dad2735bbc7a-869757534.us-east-2.elb.amazonaws.com&lt;/p&gt;

&lt;p&gt;Visit this URL in your browser to access the Spring Boot application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cleanup: Delete the EKS Cluster
&lt;/h2&gt;

&lt;p&gt;After you try this out by yourself, it’s better to delete the Kubernetes Cluster. EKS is expensive. You can use a command similar to the below to delete your EKS cluster.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;eksctl delete cluster --name eks-cluster-springboot --region us-east-2&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this guide, we successfully deployed a Spring Boot application on AWS EKS. We covered:&lt;/p&gt;

&lt;p&gt;✅ Creating a Spring Boot application ✅ Containerizing it with Docker ✅ Pushing the image to AWS ECR ✅ Deploying it in an EKS cluster ✅ Exposing it with a LoadBalancer service&lt;/p&gt;

&lt;p&gt;Now you have a fully functional Spring Boot application running on Kubernetes! Happy Coding!🚀&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>aws</category>
      <category>java</category>
    </item>
    <item>
      <title>Implementing Feature Flag Management in Your Spring Boot Application Using API Calls and UI with Togglz</title>
      <dc:creator>Chanuka Dinuwan</dc:creator>
      <pubDate>Sun, 29 Dec 2024 15:57:01 +0000</pubDate>
      <link>https://forem.com/chanuka/implementing-feature-flag-management-in-your-spring-boot-application-using-api-calls-and-ui-with-53a9</link>
      <guid>https://forem.com/chanuka/implementing-feature-flag-management-in-your-spring-boot-application-using-api-calls-and-ui-with-53a9</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb1s5db4lxu7w9zdo7qjw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb1s5db4lxu7w9zdo7qjw.png" alt=" " width="422" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In modern software development, the ability to control features in a live application without deploying new code is crucial. This capability, known as feature flag management, allows teams to turn features on or off in real-time, enabling continuous delivery, A/B testing, and canary releases. It also plays a significant role in reducing risks associated with new deployments by controlling the exposure of new features to users.&lt;/p&gt;

&lt;p&gt;In this article, we’ll walk through the process of implementing feature flag management in a Spring Boot application using Togglz. We’ll explore how to configure Togglz, define feature flags, and control their behaviour within your application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Setting Up Togglz in Your Spring Boot Application&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To get started with Togglz, you’ll need to add the necessary dependencies to your Spring Boot project. Open your build.gradle or pom.xml file and add the following dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;implementation 'org.togglz:togglz-spring-boot-starter:3.1.2'
implementation 'org.togglz:togglz-console:3.3.3'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These dependencies include the core Togglz functionality and an optional web-based console for managing your feature flags.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Configuring Togglz&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, you’ll need to configure Togglz in your Spring Boot application. This involves setting up a FeatureManager bean that Togglz uses to manage your feature flags.&lt;/p&gt;

&lt;p&gt;Here’s how you can do it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.togglz.core.manager.FeatureManager;
import org.togglz.core.manager.FeatureManagerBuilder;
import org.togglz.core.repository.jdbc.JdbcStateRepository;
import org.togglz.core.user.NoOpUserProvider;

import javax.sql.DataSource;

@Configuration
public class TogglzConfiguration {

    private final DataSource dataSource;

    @Autowired
    public TogglzConfiguration(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Bean
    public FeatureManager featureManager() {
        return new FeatureManagerBuilder()
                .featureEnum(ProductCheckFeature.class)
                .stateRepository(new JdbcStateRepository(dataSource))
                .userProvider(new NoOpUserProvider())
                .build();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DataSource: The DataSource is injected to be used by the JdbcStateRepository. This allows Togglz to persist feature flag states in a database.&lt;/li&gt;
&lt;li&gt;FeatureManager: The FeatureManager is built using a FeatureManagerBuilder. We specify the enum that defines the features (ProductCheckFeature.class), use a JdbcStateRepository for storing feature states, and a NoOpUserProvider since we’re not associating users with features in this example.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Defining Feature Flags with Enums&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Togglz uses enums to define feature flags. Each constant in the enum represents a feature that can be toggled on or off. Here’s an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.togglz.core.Feature;
import org.togglz.core.annotation.Label;

public enum ProductCheckFeature implements Feature {

    @Label("product-check")
    PRODUCT_CHECK,

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation:&lt;/p&gt;

&lt;p&gt;Label: The @Label annotation provides a human-readable name for the feature. This name will be displayed in the Togglz console if you decide to use it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Using Feature Flags in Your Application&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once the feature flags are defined and the configuration is in place, you can start using them in your application. Here’s an example of how to check if a feature is active before executing certain code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.togglz.core.manager.FeatureManager;
import reactor.core.publisher.Mono;

import javax.servlet.http.HttpServletRequest;

@RestController
@RequestMapping("/api/products")
public class ProductController {

    private final FeatureManager featureManager;
    private final ProductService productService;

    public ProductController(FeatureManager featureManager, ProductService productService) {
        this.featureManager = featureManager;
        this.productService = productService;
    }

    @GetMapping("/check")
    public Mono&amp;lt;ResponseEntity&amp;lt;?&amp;gt;&amp;gt; checkProduct(@RequestParam String isbn, HttpServletRequest httpServletRequest) {
        if (featureManager.isActive(ProductCheckFeature.PRODUCT_CHECK)) {
            return productService
                    .productCheck(isbn, JwtUtils.getUserJwt(httpServletRequest), Boolean.FALSE)
                    .flatMap(response -&amp;gt; Mono.just(ResponseEntity.ok(response)));
        } 
        return Mono.just(ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).body("Feature is disabled"));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;FeatureManager: The FeatureManager is injected into the controller and used to check if the PRODUCT_CHECK feature is active.&lt;/li&gt;
&lt;li&gt;Conditional Logic: If the feature is active, the product check operation is performed; otherwise, a “Feature is disabled” message is returned.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. Managing Feature Flags via Togglz Console&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Togglz console is a powerful tool that allows you to manage your feature flags through a web interface. To enable the Togglz console, simply add the following property to your application.properties or application.yml file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;togglz.console.enabled=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can access the console by navigating to /togglz-console in your web browser. The console provides an easy-to-use interface for turning features on or off, changing their strategies, and viewing their current state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Implementing feature flag management with Togglz in your Spring Boot application is a straightforward process that offers powerful control over your features. By following the steps outlined in this article, you can easily configure, define, and manage feature flags, allowing you to release new features with confidence and flexibility.&lt;/p&gt;

&lt;p&gt;Whether you’re rolling out a new feature gradually, conducting A/B testing, or simply want to minimize deployment risks, Togglz provides a robust solution that integrates seamlessly into your Spring Boot application.&lt;/p&gt;

&lt;p&gt;Happy Coding! 🚀&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>springboot</category>
      <category>java</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
