Guide

Backend Development 101: APIs, Databases, and Cloud Infrastructure Explained

Every app with a login, shared data, or content that changes independently of the app itself needs a backend — the server-side system that stores data and enforces the rules about who can see and change it. Here’s what that actually involves.

REST vs. GraphQL

REST structures an API as a set of endpoints, each returning a fixed shape of data for a specific resource (GET /users/123 returns a user). It’s simple, cacheable, and universally understood — the right default for most APIs, especially smaller ones or ones consumed by a single client.

GraphQL instead exposes a single endpoint where the client specifies exactly which fields it needs across potentially multiple resources in one request. This avoids the “under-fetching” (multiple round trips) or “over-fetching” (getting more data than needed) that REST can produce for complex, deeply nested data — genuinely valuable for apps with several different clients (web, iOS, Android) each needing slightly different data shapes from the same backend, but adds real complexity that isn’t worth it for a simple, single-client API.

Relational vs. NoSQL databases

Relational databases (PostgreSQL, MySQL, SQL Server) store data in structured tables with defined relationships and enforce consistency rules (a foreign key can’t point to a row that doesn’t exist) at the database level. This is the right default for most business applications — data with clear structure and relationships that need to stay consistent.

NoSQL databases (MongoDB, Firestore, DynamoDB) trade some of that structural rigidity for flexibility and, in some cases, easier horizontal scaling — well suited to data that’s naturally document-shaped, doesn’t have complex relationships, or needs to handle very high write volume across distributed regions. The common mistake is choosing NoSQL by default for its flexibility, then rebuilding relational-style constraints in application code anyway because the data actually needed them.

Authentication and authorization

Authentication confirms who a user is (login). Authorization determines what they’re allowed to do once identified — these are distinct problems, and conflating them is a common source of security bugs. Standard building blocks: JWTs (JSON Web Tokens) for stateless session tokens, OAuth2 for delegated access (letting a user log in via Google or GitHub without sharing that password with your app), and role-based access control (RBAC) for determining what an authenticated user can actually do.

Cloud infrastructure and infrastructure-as-code

Modern backends run on managed cloud infrastructure rather than physical servers — AWS, GCP/Firebase, or Azure providing compute, storage, and managed databases as billed services. Infrastructure-as-code (defining your infrastructure in version-controlled config, e.g. Terraform, rather than clicking through a cloud console) makes infrastructure changes reviewable, repeatable, and recoverable — a practice that matters increasingly as an application’s infrastructure grows past a single server.

Serverless and background jobs

Serverless functions (AWS Lambda, Azure Functions, Cloudflare Workers) run code on-demand without a persistently running server, billed only for actual execution time — a good fit for infrequent or bursty workloads. Background job queues handle work that shouldn’t block a user-facing request (sending emails, processing uploads, syncing with a third-party API), decoupling slow operations from the response the user is waiting on.

Elmeris builds backends across Node.js, Python, and .NET, on AWS, GCP/Firebase, and Azure, matched to what the project actually needs rather than one default stack for everything. See our backend development services, or get in touch to scope your API and infrastructure needs.