Background Mobile

How to Develop APIs with Backend Technologies

backend development/
September 17, 2026
How to Develop APIs with Backend Technologies

A practical guide to choosing the right backend technologies, structuring your API layer, and avoiding the mistakes that slow teams down in production.

What Does a Well-Designed API Actually Look Like?

An API is a contract. Break the contract and you break every client that depends on it. That single fact should drive most of your design decisions before you write a line of code.

A well-designed API is predictable. Consumers should be able to guess endpoint behaviour from naming alone. It is versioned from day one, not retrofitted after the first breaking change. It returns meaningful error codes, not generic 500s with no body. And it is documented in a format that can be parsed by tooling, not a PDF that goes stale within a week.

The technology you choose shapes how easy all of this is to get right.

Choosing the Right Backend Stack for Your API

This is where most architecture conversations stall. Teams argue about frameworks when they should be arguing about constraints.

The honest answer: the right stack depends on your team's existing fluency, your latency requirements, and whether your API is primarily compute-bound or I/O-bound.

Stack Best fit Watch out for
Node.js + Express / Fastify High-concurrency, I/O-heavy APIs CPU-intensive tasks block the event loop
Python + FastAPI ML-integrated services, rapid iteration GIL limits true parallelism under heavy CPU load
Go (net/http or Gin) Low-latency, high-throughput APIs Smaller ecosystem; more boilerplate for CRUD
Java + Spring Boot Enterprise, complex domain logic Memory footprint; slower startup (mitigated by GraalVM native)
Rust + Axum Maximum performance, safety-critical systems Steep learning curve; longer development cycles

FastAPI has gained significant ground for Python services because it generates OpenAPI 3.0 docs automatically from type hints. That alone eliminates a whole class of documentation drift. If your team is already in Python, it is usually the right call.

Go is genuinely worth considering if you are building something that needs to handle tens of thousands of concurrent connections with predictable tail latencies. Benchmark your actual workload though. Most APIs do not need it.

REST vs GraphQL vs gRPC

REST is still the default for good reason. It maps cleanly to HTTP semantics, caches well, and every HTTP client in existence can consume it.

GraphQL makes sense when clients have genuinely variable data requirements and you want to avoid over-fetching. It comes with costs: query complexity analysis, N+1 query problems, caching strategy changes, and a heavier server runtime.

gRPC is the right choice for internal service-to-service communication where you control both ends. Protocol Buffers give you strong typing across language boundaries and wire efficiency that JSON cannot match. HTTP/2 multiplexing removes head-of-line blocking. For public APIs, the lack of native browser support is a real constraint.

Pick the protocol that fits the actual use case. Mixing them across a single platform is normal.

How Do You Structure an API Project That Doesn't Collapse Under Its Own Weight?

Folder structure and code organisation matter more than most teams admit until they are six engineers deep into a codebase no one wants to touch.

The pattern that holds up across stacks: separate your routing, business logic, and data access layers explicitly. No database queries in route handlers. No HTTP response construction in service classes.

A typical structure in a Node.js/Fastify project:

src/
  routes/          # HTTP layer only — parse request, call service, return response
  services/        # Business logic — no knowledge of HTTP or DB driver
  repositories/    # Data access — SQL or ORM queries only
  middleware/      # Auth, rate limiting, error handling
  schemas/         # Validation and serialisation (Zod, Joi, etc.)

This is not new. It is boring. It works.

Validation belongs at the boundary. Validate request payloads before they touch your service layer. Use a schema library. In Python, Pydantic handles this automatically when you use FastAPI. In Node.js, Zod with Fastify's schema-based validation integrates cleanly. Do not trust incoming data anywhere past the route handler.

/// Not sure where to start?

Get the architecture before you commit

Tell us what you're building and we'll map the technical approach, stack, and rough timeline. No cost, no obligation, no sales call required.

Error Handling That Actually Helps Consumers

Every error response should include: an HTTP status code that matches the semantics, a machine-readable error code string, a human-readable message, and a request ID for tracing. That is the minimum. Anything less forces consumers to parse your error messages with string matching.

A 400 for validation errors, a 401 for missing auth, a 403 for insufficient permissions, a 404 for missing resources, a 409 for conflicts, and a 429 for rate limiting. Use them correctly. A 200 with an error payload in the body is a design failure.

Authentication, Authorisation, and Keeping the Perimeter Honest

JWTs are the dominant pattern for stateless auth, but they come with tradeoffs you need to understand. Once issued, a JWT is valid until it expires. Revoking one requires either a blocklist (which re-introduces state) or very short expiry windows (which require refresh token flows).

For most APIs, short-lived access tokens (15 minutes) combined with longer-lived refresh tokens (7 days) stored in HttpOnly cookies is a reasonable default. The refresh token rotation pattern, where each use issues a new refresh token and invalidates the old one, limits the blast radius of a stolen token.

OAuth 2.0 with PKCE is the standard for third-party access. If you are building a public API that other developers will integrate, implement OAuth 2.0 properly. Do not roll a custom token scheme.

Authorisation is a separate concern from authentication. Who you are (authentication) is different from what you can do (authorisation). Mixing these in a single middleware is a common mistake that makes permission logic impossible to test cleanly.

Role-based access control (RBAC) is sufficient for most use cases. Attribute-based access control (ABAC) adds flexibility at the cost of significant complexity. Use ABAC only when RBAC genuinely cannot model your permission requirements.

What Should You Monitor Once the API Is in Production?

Four numbers matter most: request rate, error rate, latency percentiles (p50, p95, p99), and saturation (queue depth or CPU). This is the RED method, originally from Weaveworks.

Do not monitor just the average latency. p99 latency tells you what your worst 1% of users are experiencing. p95 is often where SLA commitments land. Track both.

OpenTelemetry is now the standard for distributed tracing across stacks. Instrument your services with the OpenTelemetry SDK and send traces to whatever backend your team prefers (Jaeger, Grafana Tempo, Honeycomb, Datadog). The SDK abstracts the backend, so you can switch later without re-instrumenting.

Structured logs in JSON. Every log line should carry a request ID, service name, environment, and severity level at minimum. This makes log querying in tools like Loki or CloudWatch Logs Insights actually useful.

Rate limiting belongs at the gateway or reverse proxy layer, not inside your application code. NGINX, Kong, and AWS API Gateway all support it natively. Set limits per API key, not per IP, if you are running a developer-facing API.

Conclusion

The fundamentals here are not exciting, but getting them right early saves significant rework. Pick a stack your team knows, structure your code so layers have clear boundaries, validate at the entry point, handle auth correctly from the start, and instrument before you need the data not after an incident.

If you are starting a new API service and want a second set of eyes on the architecture before you commit, we are happy to talk through it.


FAQ

What is the difference between REST and GraphQL for API development? REST maps endpoints to resources and uses standard HTTP methods. GraphQL uses a single endpoint where clients specify exactly what data they need. REST is simpler to cache and monitor. GraphQL reduces over-fetching for clients with variable data requirements but adds server-side complexity around query depth, rate limiting, and N+1 query prevention.

When should I use gRPC instead of REST? Use gRPC for internal service-to-service communication where you control both ends and need strong typing across language boundaries or high-throughput, low-latency communication. For public APIs, REST is almost always more appropriate because gRPC lacks native browser support and the tooling ecosystem for public developer experience is much thinner.

How should JWT expiry be configured in production APIs? Access tokens should expire in 15 minutes or less. Refresh tokens can be valid for 7 to 30 days depending on your security requirements. Use refresh token rotation so each use invalidates the previous token. Store refresh tokens in HttpOnly cookies, not localStorage, to reduce XSS exposure.

What is the minimum viable monitoring setup for a new API? Track request rate, error rate (4xx and 5xx separately), and p95/p99 latency from day one. Add structured JSON logging with request IDs. If you are running more than one service, add distributed tracing via OpenTelemetry early. Retrofitting observability into a system under load is significantly harder than building it in from the start.

Does API versioning matter for internal APIs? Yes, even for internal APIs. Teams often skip versioning for services they control on both ends, then face coordination problems when they need to make breaking changes across multiple consumers. A simple URL path version prefix (/v1/, /v2/) with a clear deprecation policy avoids most of those problems without much overhead.

Have a project in mind? Contact Sodio Technologies to discuss your requirements and explore the right technology solution for your business.

/// Work with us

Talk to the engineers who'd build it

You'll get a technical scope, timeline and cost estimate from the people doing the work, not an account manager. In-house team, no subcontracting, since 2016.

Contact Us