• Labs icon Lab
  • Core Tech
Labs

Guided: Building a Basic Microservice with RESTful API

In this guided lab, you will build a basic microservice that exposes RESTful APIs for managing user data. You'll design clean endpoints, implement CRUD operations, and return appropriate HTTP status codes to reflect the outcome of each request. This hands-on lab introduces you to RESTful communication patterns used in microservice architecture, equipping you with practical skills to develop scalable and reliable APIs.

Labs

Path Info

Level
Clock icon Beginner
Duration
Clock icon 50m
Published
Clock icon Apr 22, 2025

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

Table of Contents

  1. Challenge

    Introduction

    In this lab, you will learn the foundational concepts of microservices and how to expose them using RESTful APIs. Microservices are independently deployable units that focus on a single business capability and interact with other services over lightweight protocols, commonly HTTP.

    This lab focuses on how to design a microservice interface that is clean, scalable, and conforms to RESTful standards. You will learn how to define meaningful endpoints, choose the right HTTP methods, and return appropriate status codes.

    While the implementation in this lab is done using Java and Spring Boot, the core ideas you will practice such as endpoint design, CRUD operation mapping, and HTTP communication are applicable across all languages and frameworks.


    You are building a user management microservice as part of a larger system. The UserService component is already implemented and handles in-memory user operations like create, retrieve, update, and delete.

    To expose this functionality as a microservice, you need to provide a RESTful interface so other services or clients can interact with it over HTTP.

    In the upcoming steps, you will create a UserController that maps HTTP requests to the appropriate service methods. This controller will act as the RESTful entry point for your microservice, enabling it to participate in a distributed system using standard REST principles. info> If you get stuck on a task, you can find the solution in the solution folder in your file tree or by clicking the Task Solution link at the bottom of each task after attempting it.

    You’re all set to begin!

  2. Challenge

    Understanding Microservices Architecture

    Monolith Architecture

    A monolithic architecture is a traditional style where all components i.e. UI, business logic, and data access are combined into a single application. While this can be simple to develop initially, it leads to several challenges:

    • Difficult to scale specific parts of the application.
    • Any change requires rebuilding and redeploying the whole system.
    • Tight coupling between components makes updates risky.
    • A single failure can bring down the entire system.

    These limitations have encouraged the shift to microservices, which offer better scalability and modularity.

    Microservices Architecture

    Microservices architecture is a development approach where a large application is broken down into a set of small, independent services. Each service focuses on a specific business capability and communicates with others using lightweight protocols such as HTTP/REST or messaging queues.


    Key Characteristics

    1. Independence

      • Services are developed, deployed, and scaled independently.
      • Each service owns a specific business domain.
    2. Loose Coupling

      • Interact via well-defined APIs or message queues.
      • Changes to one service don't heavily affect others.
    3. Technology Flexibility

      • Services can use different tech stacks based on their needs.
    4. Decentralized Data

      • Each service manages its own database.
      • Prevents tight database coupling.
    5. Fault Isolation

      • Failure in one service won’t crash the entire system.
    6. Rapid Delivery

      • Enables Continuous Integration and Deployment (CI/CD).
    7. Scalability

      • Services can be scaled individually for performance and cost efficiency.

    Benefits

    • Agility
      Build, test, and deploy faster.
    • Scalability
      Scale only the services that need it.
    • Maintainability
      Easier to manage small codebases.
    • Resilience
      Isolated failures improve system reliability.
    • Flexibility
      Choose the right tech per service.

    Challenges and Considerations

    • Increased Complexity
      Managing multiple services, deployments, and configurations requires careful coordination.

    • Latency Overhead
      Inter-service communication can introduce additional network latency.

    • Data Consistency
      Ensuring consistency across distributed services is harder than in monoliths.

    • Observability
      Requires robust logging, monitoring, and tracing to manage and debug effectively.

    • Security
      More services and APIs increase the surface area for potential vulnerabilities.


    In this step, you understood the fundamentals of microservices architecture and how it differs from monolithic architecture.

    In the next step, you'll begin designing RESTful API endpoints to structure your service effectively.

  3. Challenge

    Designing RESTful APIs

    In this step, you will explore how to design RESTful APIs that are clean, consistent, and easy to understand. REST (Representational State Transfer) is an architectural style that provides guidelines for building scalable and maintainable web services. By following these design principles, you can create APIs that are easier to use, evolve, and support over time.


    In RESTful API development, following clear and consistent resource naming conventions is essential for creating intuitive and usable endpoints. Below are some important guidelines to keep in mind:

    1. Use Nouns, Not Verbs

    Treat resources as nouns, not actions. Resource paths should represent entities (e.g., /products, /orders) rather than actions like /getProducts or /createOrder.

    2. Use Plural Form for Collections

    Keep resource names plural to indicate a collection (e.g., /products instead of /product).

    3. Hierarchical URLs for Relationships

    Represent nested resources clearly (e.g., /orders/42/items).

    4. Use Hyphens to Separate Words:

    Good Examples:/user-profiles, /product-reviews When naming resources with multiple words, use hyphens to separate them for readability and consistency.

    5. Avoid Verbosity and Redundancy

    Bad Examples: /getUsersData , /fetchProductDetails Good Examples: /users , /products Avoid including unnecessary verbs like get, fetch, retrieve, etc., as the HTTP method already implies the action being performed.

    6. Consider Hierarchy and Relationships:

    Good Examples: /users/{userId}/orders, /products/{productId}/reviews Reflect the hierarchical relationships between resources in the URL structure to maintain logical organization.


    Now you will update the UserController.java to ensure that it follows the resource naming conventions Similarly review the mapping against the createUser function. Using the plural form makes the API more intuitive and consistent with RESTful standards.


    In this step, you updated the UserController to align with RESTful API design principles by improving the naming of your endpoints.

    In the next step, you will learn about the HTTP methods GET, POST, PUT, and DELETE and how to use them effectively when designing RESTful APIs.

  4. Challenge

    Understand HTTP Methods

    HTTP Methods in RESTful APIs

    HTTP methods play a crucial role in defining the operations that can be performed on resources in a RESTful API. You will explore the appropriate use of HTTP methods and how they contribute to designing scalable and efficient APIs.

    HTTP defines several methods (also known as verbs) that indicate the desired action to be performed on a resource. The most commonly used HTTP methods in RESTful APIs are:

    | Method | Description | |----------|--------------------------------------------------------------------------| | GET | Retrieves data from a resource. | | POST | Creates a new resource. | | PUT | Updates an existing resource or creates a new one if it doesn't exist. | | PATCH | Partially updates an existing resource. | | DELETE | Deletes a resource. |


    Best Practices for Using HTTP Methods

    Use GET for Safe Operations

    • GET should retrieve data only.
    • It must be idempotent - repeated identical requests should yield the same result.

    Use POST for Creating Resources

    • Use POST to create new resources.
    • It is not idempotent - repeated POST requests may result in duplicate resources.

    Use PUT for Full Updates

    • Use PUT to update an entire resource or create it if it doesn’t exist.
    • It is idempotent - repeated requests have the same effect.

    Use PATCH for Partial Updates

    • Use PATCH to modify specific fields of a resource.
    • It is useful for small, targeted changes.

    Use DELETE for Removing Resources

    • DELETE removes a resource from the server.
    • It is idempotent - repeated calls have the same effect as one.

    Each method in a RESTful API should correspond to a specific HTTP verb that reflects the action being performed. In the next few tasks, you will update the annotations in UserController.java to ensure each method uses the correct HTTP method. info>A common mistake is using the POST method for delete operations, the correct HTTP method to use is DELETE. In this step, you learned how to properly associate controller methods with their corresponding HTTP methods. You ensured that operations like GET for retrieving data, POST for creating resources, PUT for updating resource, and DELETE for removing data are aligned with RESTful guidelines.

    In the next step, you'll continue implementing the UserController to ensure it has CRUD functionality.

  5. Challenge

    Implement CRUD Endpoints

    In this step, you will implement controller methods that delegate requests to the corresponding methods in UserService.java. You will go through a set of tasks to implement each CRUD operation by wiring the controller methods to the appropriate service layer calls. This exposes the /users endpoint using the HTTP GET method and allows clients to retrieve all user records managed by the microservice. There are two Terminal tabs, you will use the first Terminal to run the Spring boot server and the second Terminal to test the endpoints using curl.

    In ther first Terminal, navigate to the rest-microservice directory:

    cd rest-microservice
    

    Start the server by running the below command in the first Terminal :

    mvn spring-boot:run
    

    info> Please note that server is configured to run on port 8081.


    The following default users are preloaded at application startup for testing purposes:

    | User ID | Name | Email | |---------|--------------|----------------------------| | jdoe | John Doe | john.doe@mycompany.com | | asmith | Alice Smith | alice.smith@mycompany.com |

    To test the REST endpoints, use the second Terminal tab to run curl commands. The output shows that a 200 OK status code is returned, indicating the request was successful.

    However, when using a non-existent user ID such as xyz, no user details are returned, yet the response still shows a 200 status, which is not suitable for this scenario.

    curl -i -X GET http://localhost:8081/api/users/xyz
    

    In the next step, you will learn about HTTP status codes and update the UserController to return the correct status codes based on different scenarios.

  6. Challenge

    Interpret HTTP Status Codes

    HTTP status codes play a vital role in communication between clients and servers in RESTful API interactions. In this step, you will learn the significance of HTTP status codes, understand their various categories, and discover best practices for their appropriate usage in API development.

    HTTP status codes are standardized responses provided by web servers to indicate the result of a client's request. They convey information about the success or failure of the request, as well as additional context about the response.


    Categories of HTTP Status Codes

    HTTP status codes are categorized into five main classes:

    | Status Code | Description | |-------------|-----------------------------------------------------------------------------| | 1xx Informational | Indicates that the request has been received and the process is continuing. | | 2xx Success | Indicates that the request was successful and the server has fulfilled it. | | 3xx Redirection | Indicates that further action must be taken by the client to complete the request. | | 4xx Client Error | Indicates an issue with the client's request, such as invalid input or authentication failure. | | 5xx Server Error | Indicates a problem on the server while processing the request. |


    Common HTTP Status Code Examples

    • 200 OK
      Successful response to a GET request.
    • 201 Created
      A new resource was successfully created via a POST request.
    • 400 Bad Request
      The request is invalid due to client-side input errors.
    • 401 Unauthorized
      Authentication credentials are missing or invalid.
    • 404 Not Found
      The requested resource could not be located.
    • 500 Internal Server Error
      The server encountered an unexpected condition.

    Now that you’re familiar with common HTTP status codes, your next task is to identify and apply the appropriate status codes to REST API responses.

    info> Note: In the Spring Framework, you can use the HttpStatus enum to represent HTTP response status codes, as shown below:

    | HTTP Status Code | Spring Representation | |------------------|---------------------------------| | 200 | HttpStatus.OK | | 201 | HttpStatus.CREATED | | 204 | HttpStatus.NO_CONTENT | | 404 | HttpStatus.NOT_FOUND | | 500 | HttpStatus.INTERNAL_SERVER_ERROR | Now you will modify the getUserById() method so that if no user is found for the provided ID, the client receives a 404 (Not Found) status code. Next, you will update the createUser() method. Currently, it returns a 200 status, but it should return 201 (Created) to indicate that a new resource has been successfully created.

    Additionally, if any required user details such as the user is missing, the method should return a 400 (Bad Request) status. You can now test your RESTful microservice using the curl commands below to verify each endpoint and observe the corresponding HTTP status codes.

    In the first Terminal, press CTRL + C to stop the Spring Boot server if it's currently running. A restart is needed to ensure the latest code changes are applied.

    Ensure you're in the /rest-microservice directory. If not, you can cd into it.

    cd rest-microservice
    

    Start the server:

    mvn spring-boot:run
    

    Then, in the second Terminal, execute the following curl commands:


    Get All Users

    curl -i -X GET http://localhost:8081/api/users
    

    Get User by ID

    curl -i -X GET http://localhost:8081/api/users/jdoe
    

    Replace jdoe with any existing or non-existing user ID to test 200 or 404 responses.


    Create New User

    curl -i -X POST http://localhost:8081/api/users 
      -H "Content-Type: application/json" 
      -d '{"id":"sking","userName":"Stephen King","userEmail":"stephen.king@mycompany.com"}'
    

    Update Existing User

    curl -i -X PUT http://localhost:8081/api/users/asmith 
      -H "Content-Type: application/json" 
      -d '{"userName":"Alice Smith Updated","userEmail":"alice.updated@mycompany.com"}'
    

    Delete User

    curl -i -X DELETE http://localhost:8081/api/users/asmith
    ``` ---
    In this step, you learned how HTTP status codes are used to communicate the outcome of requests in a RESTful API. You explored the different categories of status codes, from informational to server errors, and understood how to apply them in practical scenarios.
    
    **Congratulations!**  
    You have successfully created a RESTful microservice !
  7. Challenge

    Conclusion and Next Steps

    Conclusion

    In this lab, you built a basic microservice that exposes a RESTful API to manage users. You:

    • Understood the concept of a microservice and how they interact over HTTP.
    • Implemented CRUD operations using RESTful endpoints.
    • Mapped HTTP methods like GET, POST, PUT, and DELETE to controller actions.
    • Returned meaningful HTTP status codes for different outcomes.

    This hands-on experience helped you understand how microservices communicate through HTTP and how to expose business logic cleanly via RESTful APIs.


    Next Steps

    To further enhance your understanding and build production-grade microservices, consider exploring:

    • API Design Enhancements: Support for pagination, filtering, and sorting.
    • Error Handling: Standardized error responses and global exception handling.
    • Security: Securing APIs using authentication and authorization mechanisms such as API keys, tokens, or OAuth.
    • Observability: Adding logging, metrics, and tracing to monitor service behavior and performance.
    • Service Communication: Understanding inter-service communication patterns like service discovery and retries.

    These next steps will help you build scalable, secure, and observable microservices suited for real-world systems.

Amar Sonwani is a software architect with more than twelve years of experience. He has worked extensively in the financial industry and has expertise in building scalable applications.

What's a lab?

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Provided environment for hands-on practice

We will provide the credentials and environment necessary for you to practice right within your browser.

Guided walkthrough

Follow along with the author’s guided walkthrough and build something new in your provided environment!

Did you know?

On average, you retain 75% more of your learning if you get time for practice.