When I started developing APIs, I was confused about the naming and decided to ignore them completely. I designed my own way of building and organizing the code. Later, with simple steps, I had my own framework, and I realized that I ended up with something that has been used by many developers. It was mini framework that in the end had controllers and services. However I did not all them like that but instead I called them differently.
Today I make use of the naming like controllers and services, because I actually understand what this means, but I wish I had a simple way to understand this from the beginning. So what are controllers and services in API design.
In API design, controllers and services are two key components that help organize your code and make it easier to manage. Think of it like ordering food at a restaurant:
Controllers 🍽️
A controller is like the waiter in a restaurant.
- It takes your order (the API request). When you (the client) send a request to the API (e.g., “I want to get user information”), the controller is the first thing that receives it.
- It understands what you want. It figures out what operation you’re trying to perform (e.g., get user, create user, update user).
- It doesn’t cook the food itself. The waiter doesn’t go into the kitchen to prepare your meal.
- It brings you the food (the API response). Once the “kitchen” (the service) has prepared what you asked for, the controller takes that result and sends it back to you.
Key jobs of a controller:
- Receiving incoming HTTP requests (e.g., GET, POST, PUT, DELETE).
- Validating the request (e.g., are all required parameters present?).
- Calling the appropriate service to do the actual work.
- Formatting the response to send back to the client (e.g., as JSON).
Services 🧑🍳
A service is like the chef in the restaurant’s kitchen.
- It knows how to prepare the dish (handle the business logic). The service contains the actual logic for what needs to be done. If you want user information, the service knows how to find that user in the database.
- It does the actual work. It interacts with the database, performs calculations, calls other services if needed, etc.
- It gives the prepared dish back to the waiter. Once the service has done its job (e.g., retrieved the user data), it returns that data to the controller.
Key jobs of a service:
- Implementing the core business logic of your application.
- Interacting with data sources (like databases).
- Performing calculations or data transformations.
- Ensuring data integrity and consistency.
Example: Getting User Information 🙋
Let’s say you have an API endpoint /users/{id}
to get information about a specific user.
- You (the client) send a GET request to
/users/123
. - The
UserController
(the waiter) receives this request.- It understands you want to get user information for the user with ID
123
. - It might check if
123
is a valid ID format.
- It understands you want to get user information for the user with ID
- The
UserController
calls theUserService
(the chef).- It says, “Hey
UserService
, please get me the user with ID123
.”
- It says, “Hey
- The
UserService
does the work.- It connects to the database.
- It runs a query like
SELECT * FROM users WHERE id = 123;
. - It gets the user data (e.g., name: “Alice”, email: “[email protected]”).
- It returns this user data to the
UserController
.
- The
UserController
receives the user data from theUserService
.- It formats this data into a standard response (e.g., a JSON object:
{"id": 123, "name": "Alice", "email": "[email protected]"}
). - It sends this JSON response back to you (the client).
- It formats this data into a standard response (e.g., a JSON object:
Why separate them?
- Organization: Keep your code clean. Controllers handle API stuff (requests/responses), services handle business logic.
- Reusability: A service can be used by multiple controllers or even other services. For example, one
OrderService
might use theUserService
to get customer details. - Testability: It’s easier to test business logic in services separately from the API request/response handling in controllers.
So, controllers manage the “how” of API communication, while services manage the “what” and “why” of the application’s tasks.