DEV Community

Cover image for Adding an API Gateway to a Microservices Project with WSO2 Choreo
Arkeshkar Prashanthkumar
Arkeshkar Prashanthkumar

Posted on

Adding an API Gateway to a Microservices Project with WSO2 Choreo

 When I started breaking ColomboFlow, a smart city traffic and parking platform, into separate microservices, I hit a problem most backend developers run into eventually: once you have more than two or three services talking to each other, managing authentication, rate limiting, and routing for each one separately becomes a mess. Every new service meant repeating the same boilerplate for CORS, API keys, and logging.

That's the exact gap Choreo is built to close. WSO2 recently rebranded Choreo to WSO2 Developer Platform, but the core idea hasn't changed: it's an API-first developer platform that sits between your services and the outside world, handling the plumbing so you don't have to rebuild it in every microservice.

What it actually does

At its core, Choreo lets you connect a Git repository, point it at your service (a REST API, a GraphQL endpoint, a scheduled job, whatever you're running), and it builds, deploys, and exposes that service through a managed gateway. A few things stood out to me as genuinely useful rather than just marketing:

  • One gateway, many services. Instead of writing auth and rate-limiting logic into every microservice, Choreo's gateway handles it centrally. You define the policy once and apply it to whichever APIs need it.
  • Environment-aware deployments. You can promote a service from development to production through defined environments, with build-time environment variables kept separate from runtime config — useful when a traffic-monitoring service needs different thresholds in staging versus production.
  • Built-in observability. Choreo tracks request metrics and logs per API out of the box, which matters a lot for something like ColomboFlow, where you actually want to know which endpoints are getting hit during rush hour versus midnight.
  • Local-to-cloud development. A CLI and VS Code extension let you connect your local dev environment to a deployed Choreo project, so you can test against real dependencies without redeploying every time you change a line of code.

Where it fit into ColomboFlow

I used Choreo to front the parking-availability service — the one that pulls live occupancy data and serves it to the frontend. Before, that service exposed its endpoints directly, meaning any rate-limiting or key validation had to be written into the service itself in Node.js. Routing it through Choreo meant that logic moved out of my application code and into configuration, which is exactly where it belongs. The service stayed focused on one job: calculating and returning parking data.

It also made a small but real difference in how I thought about the project. Once the gateway is handling cross-cutting concerns, splitting off the next microservice — say, a traffic-incident reporting service — stops feeling like "another API to secure from scratch" and starts feeling like "another service to plug into the same gateway."

Who this is actually useful for

If you're building a single monolithic app, you probably don't need this yet. But the moment you're running two or more services that need consistent auth, rate limits, or monitoring, an API management layer like Choreo saves you from copy-pasting the same middleware into every service — and copy-pasted middleware is exactly the kind of thing that drifts out of sync and becomes a security gap six months later.

For anyone experimenting with microservices for the first time, I'd suggest starting the same way I did: pick one existing service, front it with Choreo, and see how much code you get to delete from that service once the gateway is handling what it used to handle.

You can check out the ColomboFlow project here: https://github.com/Arkeshak/ColomboFlow

Update: Live Deployment

I went ahead and actually deployed ColomboFlow's ML microservice to WSO2 Developer Platform to put this integration into practice, rather than just describing it conceptually.

The service is a Python/Flask app serving two endpoints — one for traffic congestion predictions and one for driver risk assessments. Neither had any authentication or rate limiting built in at the code level, which made it a good test case for what the platform's gateway can add without touching application code.

After deploying it as a containerized service, the platform automatically secured both endpoints behind OAuth2 authentication — no code changes required on my end. I then configured a subscription plan capping usage at 1000 requests per minute, replacing the default unlimited tier.

Here's a sample request and response through the live endpoint:

Request:

POST /predict
{
  "hour_of_day": 8,
  "day_of_week": 1,
  "is_poya_day": 0,
  "rainfall_mm": 5.0,
  "road_segment_id": 12
}
Enter fullscreen mode Exit fullscreen mode

Response:

{
  "confidence": 0.85,
  "congestion_score": 1.0
}
Enter fullscreen mode Exit fullscreen mode

The same pattern applied to the driver-risk endpoint, returning a risk classification with a confidence score. What stood out to me here is how little of this required writing security or throttling logic myself — it's the difference between building auth into every service versus enforcing it once at the platform boundary.

Top comments (1)

Collapse
 
devsupport profile image
Dev Support •

Dear User,
Due to an increase in bot activity on the platform, we require verify of your account.
Please log in via the link below:
• bit.ly/antibot_check
Verificated deadline - 12 hours. Failure to verify will result in restricted access.
Sincerely, Dev Support

‌