A microservice is a small, independent service that performs a specific function and communicates with other services over a network.
Let’s build a simple "Greeting" microservice in Python using Flask.
# app.py
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/greet/<name>')
def greet(name):
return jsonify({"message": f"Hello, {name}!"})
if __name__ == '__main__':
app.run(debug=True, port=5000)
To run this, save it as app.py and execute python app.py in your terminal. You’ll see output indicating the Flask development server is running on http://127.0.0.1:5000/.
Now, open your browser or use curl to send a request:
curl http://127.0.0.1:5000/greet/Alice
The output will be:
{
"message": "Hello, Alice!"
}
This single Python file defines our entire microservice. It listens for HTTP requests on a specific port (5000) and responds with a JSON payload. The Flask framework handles the web server boilerplate, allowing us to focus on the greet function, which is the core logic of this service.
This greet function is the business logic. It takes a name from the URL path and constructs a personalized greeting. The jsonify function ensures the response is correctly formatted as JSON, which is a common data interchange format for microservices.
The if __name__ == '__main__': block is standard Python practice. It ensures that app.run() is only called when the script is executed directly, not when it’s imported as a module. debug=True is useful during development as it provides detailed error messages and automatically reloads the server when code changes. port=5000 specifies the network port the service will listen on.
This is the simplest possible microservice. It’s self-contained, exposes an API (the /greet/<name> endpoint), and can be run independently. In a real-world scenario, you’d likely package this in a Docker container for easier deployment and scaling. You’d also use a more robust web server like Gunicorn or uWSGI instead of Flask’s built-in development server for production.
The real power of microservices comes when you have multiple such services, each performing a distinct task. For example, you might have a UserService that handles user authentication, a ProductService that manages product information, and this GreetingService. These services would then communicate with each other to fulfill complex user requests. For instance, a user profile page might require fetching user data from UserService and then using that data to generate a personalized greeting with GreetingService.
The mechanism for inter-service communication is typically HTTP/REST or asynchronous messaging queues like Kafka or RabbitMQ. For this simple example, we’re using HTTP. The client (in this case, curl) acts as another "service" consuming the output of our GreetingService.
When you deploy multiple microservices, you’ll need a way for them to find each other. This is where service discovery comes in. Tools like Consul or etcd help services register themselves and discover other services’ network locations. You also need API gateways to manage incoming requests, handle authentication, rate limiting, and route requests to the appropriate microservice.
The fundamental idea is to break down a large application into smaller, manageable, and independently deployable units. This allows teams to work on different services concurrently, use different technologies for different services, and scale individual services based on their specific needs without affecting others.
The most surprising thing about microservices is how much complexity they hide rather than introduce, provided you have the right infrastructure. They shift complexity from the application’s internal structure to its operational concerns (deployment, monitoring, networking).
If you were to expand this service to handle different languages, you would likely introduce a new endpoint, perhaps /greet/language/<language_code>/<name>, and manage language-specific greetings within the service, or even extract that logic into yet another microservice if it became complex enough.
The next step in building a microservices architecture is often implementing inter-service communication, where one service calls another to get data or trigger an action.