- Lab
- Core Tech

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.

Path Info
Table of Contents
-
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 thesolution
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!
-
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
-
Independence
- Services are developed, deployed, and scaled independently.
- Each service owns a specific business domain.
-
Loose Coupling
- Interact via well-defined APIs or message queues.
- Changes to one service don't heavily affect others.
-
Technology Flexibility
- Services can use different tech stacks based on their needs.
-
Decentralized Data
- Each service manages its own database.
- Prevents tight database coupling.
-
Fault Isolation
- Failure in one service won’t crash the entire system.
-
Rapid Delivery
- Enables Continuous Integration and Deployment (CI/CD).
-
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.
-
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 likeget
,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 thecreateUser
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.
-
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 likeGET
for retrieving data,POST
for creating resources,PUT
for updating resource, andDELETE
for removing data are aligned with RESTful guidelines.In the next step, you'll continue implementing the
UserController
to ensure it has CRUD functionality. -
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 theHTTP 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 usingcurl
.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 a200 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 a200
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. -
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 aGET
request. - 201 Created
A new resource was successfully created via aPOST
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 thegetUserById()
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 thecreateUser()
method. Currently, it returns a200
status, but it should return201
(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 thecurl
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 cancd
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 !
- 200 OK
-
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.
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.