Web APIs
A service exposed over plain HTTP, as resources with URLs (REST) or as one typed graph (GraphQL), so any browser, app or partner can call it.
2 technologies on this page ↓How it works
A web API puts a service behind ordinary HTTP, so anything with an HTTP client can call it: a browser, a phone app, a partner’s server, a script with curl. REST, the most common style, gives each thing the API deals with its own URL, such as /orders/4812, and uses HTTP’s own methods on it: GET reads, PUT replaces, DELETE removes, POST creates or triggers an action. The server answers with a representation, usually JSON, and a status code such as 200, 201 Created, 404 or 409 Conflict. HTTP defines GET as safe and GET, PUT and DELETE as idempotent, so clients and proxies know which requests they can repeat after a timeout, and caches can keep a GET response for as long as its Cache-Control header allows, then check it again cheaply with its ETag. Each request carries everything needed to answer it, so any server behind a load balancer can take it. GraphQL works differently: one endpoint, usually POST /graphql, and a typed schema describing all the objects and how they connect. The client sends a query naming exactly the fields it wants, across related objects; the server validates it against the schema, runs a resolver function for each field to fetch the data, and returns JSON shaped like the query. Two pieces often sit alongside: an OpenAPI document that describes a REST API’s paths and payloads so docs, tests and client code can be generated from it, and webhooks, where the API calls you: it sends an HTTP POST to a URL you registered when something happens. Compared with RPC frameworks such as gRPC, the contract is URLs and HTTP’s rules (or a GraphQL schema) rather than generated stubs and binary messages, which makes calls easy to read, debug and cache but larger and less strictly typed. An API gateway is a separate layer in front that checks keys, enforces limits and routes calls; it doesn’t decide how the API itself is shaped.
REST is a well-signposted warehouse: every item has its own shelf address and you use the same few actions everywhere (look, put, remove), so any visitor can find their way. GraphQL is handing the clerk at the counter one order form listing exactly what you want from several aisles, and getting it back in a single bag.
Reach for it when
- Public or partner APIs that unknown clients, written in any language, must be able to call with an ordinary HTTP library
- Backends for web and mobile front ends, which already speak HTTP and JSON
- Read-heavy data that browsers and CDNs can cache: REST
GETresponses withCache-Controland anETag - Screens that combine many related objects, where GraphQL lets each client fetch exactly the fields it needs in one round trip
- Telling other companies’ systems that something happened, with webhooks instead of having them poll
Think twice when
- High-volume calls between your own services, where gRPC’s binary encoding, generated stubs and streaming save bytes and guesswork
- Work that can wait or must survive the receiver being down; put it on a queue
- A steady stream of updates to clients: polling a REST endpoint wastes requests; use WebSockets, server-sent events or GraphQL subscriptions
- A public GraphQL API without depth or cost limits, where one nested query can fan out into a huge number of backend calls
A real example
A shop’s product page calls GET /products/981. The response carries Cache-Control: max-age=60 and ETag: "v7", so the CDN answers most requests for that minute, and afterwards a browser that asks with If-None-Match: "v7" gets an empty 304 Not Modified if nothing changed. A partner places an order with POST /orders and gets 201 Created with Location: /orders/4812; when its later PUT /orders/4812/address times out, it simply sends it again, because PUT is idempotent. The mobile app’s order screen sends one GraphQL query for the order’s status, its line items and the customer’s name instead of three REST calls. When the parcel ships, the shop sends a signed order.shipped webhook to the URL the partner registered.
More on web apis
Narrower ideas that build on this one.
Technologies
Specific products, and what each does differently.
| Open source | GraphQL Foundation (Linux Foundation), created at Facebook | Specification: Open Web Foundation Agreement 1.0 since September 2017; GraphQL.js reference implementation: MIT since September 2017 (BSD plus a patent grant before) | 2026-10-09 | |
| REST | Open source | Architectural style (Roy Fielding, 2000); HTTP itself is an IETF standard | – | 2026-10-06 |
What each provider calls it
- AWS
- API Gateway for REST: REST APIs (API keys, usage plans, caching, request validation) or the cheaper, leaner HTTP APIs, in front of Lambda or any HTTP backend. AppSync for managed GraphQL, with resolvers that read DynamoDB, Lambda, OpenSearch, RDS, EventBridge or HTTP endpoints, plus real-time subscriptions
- Google Cloud
- API Gateway (OpenAPI 2.0, 3.0 or 3.1 specs in front of Cloud Run, Cloud Functions and App Engine); Cloud Endpoints; Apigee for full API management, including a GraphQL policy that checks queries against a schema; Firebase Data Connect for a managed GraphQL API over Cloud SQL for PostgreSQL
- Azure
- API Management, for REST APIs imported from OpenAPI and for GraphQL APIs, either passed through to an existing GraphQL server or synthesised from a schema with resolvers; Data API builder, a free open-source engine that serves REST and GraphQL over SQL Server, Azure SQL, Cosmos DB, PostgreSQL and MySQL
- Open source & others
- REST frameworks such as FastAPI and Express; GraphQL servers such as GraphQL.js, Apollo Server, GraphQL Yoga, graphql-java and Strawberry; APIs generated from a database: PostgREST, Hasura, PostGraphile, pg_graphql; the OpenAPI Specification and its tooling; the Standard Webhooks spec for signed callbacks
In code · http
# REST: the URL names the resource, the method says what to do
GET /orders/4812 HTTP/1.1
Host: api.example.com
Accept: application/json
If-None-Match: "v7"
HTTP/1.1 304 Not Modified
ETag: "v7"
Cache-Control: private, max-age=60
# GraphQL: one endpoint; the query says which fields to return
POST /graphql HTTP/1.1
Host: api.example.com
Content-Type: application/json
Accept: application/graphql-response+json
{"query": "query($id: ID!) { order(id: $id) { status customer { name } } }", "variables": {"id": "4812"}}
HTTP/1.1 200 OK
Content-Type: application/graphql-response+json
{"data": {"order": {"status": "PAID", "customer": {"name": "Ada"}}}}Often confused with
Where it came from1999–2022
The first web services used HTTP as a pipe. XML-RPC, specified by Dave Winer in 1999, sent a procedure call as XML in an HTTP POST, and SOAP, published as a W3C Note in May 2000, wrapped calls in XML envelopes. Every call was a POST to one URL, so caches and proxies couldn’t tell a harmless read from an order being placed.
In 2000 Roy Fielding, a principal author of HTTP/1.0 and HTTP/1.1, named the style he had used since 1994 to guide those standards: Representational State Transfer, or REST. Resources have URLs, every component uses the same small set of methods, requests are stateless and responses say whether they can be cached. When Amazon S3 launched in March 2006 it offered “standards-based REST and SOAP interfaces”; S3 has since deprecated SOAP over plain HTTP. Swagger, created in 2010, gave REST APIs a machine-readable description, and in 2015 it became the OpenAPI Specification under the Linux Foundation.
Mobile apps exposed REST’s weak spot. Rebuilding its native apps in 2012, Facebook found that fetching News Feed meant many requests and responses shaped by the server, not by the screen. Its answer, GraphQL, let the client ask for exactly the fields it needed in one request. Facebook open-sourced it in 2015, and in 2016 GitHub launched the first major public GraphQL API.
Why it’s built this way
- HTTP’s own methods and status codes instead of a tunnel
- Fielding argued that a uniform interface makes interactions visible to every component in between, so caches, proxies and gateways can act on a request without knowing the application. The price, in his words, is that it “degrades efficiency”, because data travels in a standard form rather than one fitted to each application.
- Stateless requests
- Each request must carry everything needed to understand it, so the server keeps no session between calls. Fielding accepted repeating some data in every request in exchange for visibility, easier recovery from partial failures, and servers that free resources quickly and scale.
- A machine-readable description of the API
- Swagger, and then OpenAPI, describe paths, parameters and payloads in a file that humans and tools can both read, so documentation, tests and client code can be generated instead of written by hand for each language.
- Let the client choose the shape of the response
- Facebook’s mobile developers were frustrated by the gap between the data their apps wanted and the server queries they had to call. GraphQL’s hierarchical queries follow relationships between objects in one request, where REST may need several round trips on a slow mobile network.
Timeline
- 1999
Dave Winer publishes the XML-RPC specification
- 2000
SOAP 1.1 published as a W3C Note; Fielding’s dissertation defines REST
- 2006
Amazon S3 launches with REST and SOAP interfaces
- 2015
Facebook open-sources GraphQL; the OpenAPI Initiative forms around Swagger
- 2016
GitHub launches the first major public GraphQL API
- 2022
RFC 9110 and RFC 9111 restate HTTP’s semantics and caching rules
- XML-RPC specification (Dave Winer, June 1999)
- W3C Note: Simple Object Access Protocol (SOAP) 1.1 (May 2000)
- Roy Fielding: Architectural Styles and the Design of Network-based Software Architectures, chapter 5: REST (UC Irvine, 2000)
- Roy Fielding: dissertation, chapter 6: Experience and evaluation (REST since 1994, HTTP/1.0 and HTTP/1.1)
- Amazon press release: Amazon Web Services launches Amazon S3 (March 2006)
- Amazon S3 API reference: Welcome (REST API; SOAP over HTTP deprecated)
- Linux Foundation: New collaborative project to extend Swagger specification (Open API Initiative, November 2015)
- GraphQL blog: GraphQL, a data query language (Lee Byron, September 2015)
- GraphQL blog: Leaving technical preview (GitHub GraphQL API, September 2016)
Sources31
- RFC 9110: HTTP Semantics (methods, safe and idempotent methods, status codes, conditional requests)
- RFC 9111: HTTP Caching (freshness, validation, invalidation after unsafe methods)
- Roy Fielding: dissertation, chapter 5: REST (stateless, cache and uniform interface constraints)
- GraphQL specification, September 2025 edition
- GraphQL docs: Serving over HTTP (single endpoint, POST and GET, media types, status codes)
- GraphQL docs: Performance (N+1 problem, DataLoader, GET and persisted queries)
- GraphQL docs: Security (depth limiting, query complexity, trusted documents)
- OpenAPI Specification v3.2.1 (paths, webhooks)
- Standard Webhooks specification (HTTP POST, webhook-id, HMAC signatures)
- API Gateway docs: Choose between REST APIs and HTTP APIs
- AWS AppSync docs: What is AWS AppSync?
- AWS AppSync docs: Data sources (DynamoDB, Lambda, OpenSearch, HTTP, RDS, EventBridge)
- Google Cloud docs: About API Gateway
- Google Cloud docs: API Gateway OpenAPI overview (supported versions)
- Google Cloud docs: About Cloud Endpoints
- Apigee docs: GraphQL policy
- Firebase docs: Firebase Data Connect
- Microsoft Learn: Overview of GraphQL APIs in Azure API Management (pass-through and synthetic)
- Microsoft Learn: Import an OpenAPI specification to Azure API Management
- Microsoft Learn: What is Data API builder?
- FastAPI on GitHub
- Express on GitHub
- GraphQL.js on GitHub
- Apollo Server on GitHub
- GraphQL Yoga on GitHub
- graphql-java on GitHub
- Strawberry GraphQL on GitHub
- PostgREST on GitHub
- Hasura GraphQL Engine on GitHub
- PostGraphile (graphile/crystal) on GitHub
- pg_graphql docs