I have shipped REST APIs for four years (Flask, AWS Lambda + API Gateway, FastAPI). This is the reference I use in design reviews and phone screens — focused on when to pick each style, not memorising definitions.
Companion on Medium: REST vs SOAP vs GraphQL vs gRPC: How I Actually Choose — decision framework with trade-offs.
1. REST in 60 seconds
REST models resources (nouns) and uses HTTP methods (verbs).
GET /users/7 read safe + idempotent
POST /users create not idempotent
PUT /users/7 replace all idempotent
PATCH /users/7 change some usually not idempotent
DELETE /users/7 remove idempotent
Enter fullscreen mode Exit fullscreen mode
Safe = does not change server data (GET).
Idempotent = 1 call or 10 identical calls leave the same state (GET, PUT, DELETE).
Status codes I treat as required:
Code Meaning I say in interviews 200 Success 201 New resource created (typical POST) 400 Client sent a bad request (invalid JSON / missing field) 401 Unauthenticated — I do not know who you are 404 That URL or id does not exist 500 Server failed — do not “fix the JSON”401 vs 403: 401 = who are you? 403 = I know you; you are not allowed.
What makes an API RESTful (5 bullets):
- Resources in the URL, not action names
- Uniform HTTP methods and status codes
- Stateless requests (auth + ids on every call)
- Representations (usually JSON)
- Correct verb + code pairing (GET does not write; create → 201)
2. The comparison interviewers want
REST SOAP GraphQL gRPC Style Resources + HTTP XML envelope + WSDL Query language, one endpoint RPC + Protobuf Payload JSON (usually) XML JSON Binary protobuf Contract Informal / OpenAPI Strict WSDL Schema (SDL).proto
Typical transport
HTTP/1.1
HTTP POST
HTTP POST
HTTP/2
Browser-friendly
Yes
Painful
Yes
Not natively
Caching
Natural on GET
Weak
Harder
Weak
Best at
Public / mobile APIs
Enterprise partner contracts
Many clients, custom shapes
Internal service-to-service
Weak at
Chatty mobile graphs
New greenfield APIs
Simple CRUD, HTTP cache
Public curl + JSON
SOAP
SOAP is a protocol. You send XML. The operations live in a WSDL. Almost every call is POST. HTTP methods are not the API.
Use it when the other organisation already requires the contract (finance, government, older healthcare integrations). Do not start a new B2C API in SOAP in 2026 if you control both sides.
GraphQL
One endpoint. The client asks for exact fields. Solves over-fetching.
Watch for: cache keys, expensive queries, auth on a single URL that does many jobs.
gRPC
HTTP/2 + Protobuf. Typed generated clients. Streaming. Fast inside your own network.
Do not expose this as your public mobile API unless you have a gateway. Partners and browsers want JSON.
Also mentioned, not replacements
- JSON-RPC — call a method name. Fine internally. Easy to invent RPC soup.
- WebSockets — persistent two-way. Live updates, not CRUD.
3. Decision rules I actually use
Need a public or mobile API? → REST
Partner handed you a WSDL? → SOAP
Clients need different slices of the same graph? → GraphQL
Service-to-service, low latency, typed? → gRPC
Need live updates after first load? → WebSockets (+ REST for the first load)
Unsure? → REST, then add a BFF later
Enter fullscreen mode Exit fullscreen mode
Starting with the heaviest option is how designs stall. REST is reversible.
4. Tiny examples (same “create user” idea)
REST
POST /users HTTP/1.1
Content-Type: application/json
{"name":"Aisha","email":"[email protected]"}
Enter fullscreen mode Exit fullscreen mode
201 Created + Location: /users/7
SOAP (shape only — do not memorise the XML)
<soap:Envelope>
<soap:Body>
<CreateUser>
<name>Aisha</name>
<email>[email protected]</email>
</CreateUser>
</soap:Body>
</soap:Envelope>
Enter fullscreen mode Exit fullscreen mode
Posted to one /service URL. The operation is inside the body.
GraphQL
mutation {
createUser(name: "Aisha", email: "[email protected]") {
id
email
}
}
Enter fullscreen mode Exit fullscreen mode
Usually POST /graphql. You choose the fields in the response.
gRPC (.proto)
service UserService {
rpc CreateUser (CreateUserRequest) returns (User);
}
Enter fullscreen mode Exit fullscreen mode
Binary on the wire. Generated stubs in Python, Go, Java.
5. What I say in 45 seconds
I default to REST: nouns in the URL, verbs in the method, JSON on the wire. GET is safe. PUT and DELETE are idempotent. POST is not — a double-tap can create two rows.
SOAP when the partner already has a WSDL.
GraphQL when over-fetching is a real product problem.
gRPC for internal service-to-service, not browsers.
The decision is the problem, not the acronym.
Further reading
Muhammad Umair Virk — Backend Engineer, UAE. Python · AWS · microservices · payments.