A contract between two programs
You have used a thousand APIs today without seeing one. When your phone showed the weather, it did not scrape a website; it asked a weather service a precise question and got a precise answer back, in a format it knew in advance how to read. That agreement — you may ask me these questions, in this shape, and I will answer in that shape — is an API: an application programming interface, the front counter one program offers to another. The classic image is the restaurant. You never walk into the kitchen; you read a menu, tell a waiter "the salmon," and food arrives. The menu is the API: it lists what you may order and hides everything about how the kitchen works. You do not know the chef's name, the supplier, or the stove — and that ignorance is the point, because the kitchen can change all of it without changing your dinner.
Class Sixteen already told you the sentence this part unpacks: everything in Azure is an API. When you run az vm create, the CLI is a waiter carrying your order to the Azure Resource Manager API; the portal is a fancier waiter for the same kitchen. This part slows that down to the level a gateway operates at, because API Management reads requests for a living, and you cannot throttle, authenticate, or route a thing you cannot read. Get the language here and the remaining seven parts stop being portal clicks and become sentences you understand.
The menu hides the kitchen on purpose.
REST and the verbs — the web's own API style
Most APIs you will meet on Azure are REST APIs, and REST is less a technology than a set of manners layered on the HTTP you already use to load web pages. Its central idea is the resource: a noun with an address. A product is a resource at /products/42; the whole catalog is a resource at /products. You do not invent a verb for every action — getProduct, deleteProduct — the way an older style did. Instead you name the noun in the URL and use one of HTTP's small set of standard verbs to say what to do to it. That constraint is what makes a gateway possible: because the verb and the noun live in the request in a predictable place, a gateway can route on them without understanding your application at all.
REST is also stateless: every request carries everything the server needs to answer it, and the server remembers nothing between calls. That single property is why a gateway can sit in the middle, why any of a dozen identical backends can answer the next call, and why scaling out works. It is the same idea Class Thirteen's load balancer relied on, seen from the API side.
| Verb | Means | Safe? | Idempotent? |
|---|---|---|---|
| GET | Read a resource; never change it | Yes | Yes |
| POST | Create a new resource, or trigger an action | No | No |
| PUT | Replace a resource wholesale at a known address | No | Yes |
| PATCH | Modify part of a resource | No | No |
| DELETE | Remove a resource | No | Yes |
Safe means the call has no side effects — a GET must never change data, which is why a gateway may cache it and a crawler may repeat it. Idempotent means doing it twice lands you where doing it once would: deleting an already-deleted product is still "gone," so a client that times out can safely retry a DELETE or PUT, but retrying a POST may create two orders. That distinction is not pedantry — it decides whether a retry policy is safe, and it is exactly the kind of thing the gateway in 38d will enforce.
Status codes — how the answer says how it went
Every HTTP response opens with a three-digit status code, and reading them fluently is the difference between an engineer who debugs an integration in minutes and one who reads logs for an afternoon. The first digit sorts them: 2xx the request succeeded, 3xx go somewhere else, 4xx the caller got it wrong, 5xx the server got it wrong. That fourth-versus-fifth split is the one that matters most on the job, because it decides whose bug it is: a 4xx means stop retrying and fix your request; a 5xx means the server failed and a retry might work.
| Code | Name | What it tells the caller |
|---|---|---|
| 200 | OK | Success, with a body — the everyday GET reply |
| 201 | Created | A POST made a new resource; its address is in the response |
| 204 | No Content | Success, nothing to return — a common DELETE reply |
| 400 | Bad Request | The request itself is malformed; fixing the server will not help |
| 401 | Unauthorized | No valid credential — the gateway did not learn who you are |
| 403 | Forbidden | Known caller, but not allowed this operation |
| 404 | Not Found | No resource at that address |
| 409 | Conflict | The request fights the current state — a duplicate, a race |
| 429 | Too Many Requests | You hit a rate limit — slow down and read Retry-After |
| 500 | Server Error | The backend broke; not your fault, maybe worth a retry |
| 503 | Service Unavailable | The backend is overloaded or down; back off and retry |
Two of these are load-bearing for the rest of the track. 401 versus 403 is the whole of authentication versus authorization in two codes: 401 says I do not know who you are; 403 says I know exactly who you are and the answer is still no. And 429 is the sound a gateway makes when it does its job — the polite refusal that turns a runaway caller into a status code instead of an outage. Half of 38d exists to produce a well-formed 429.
The request, the response, and the contract
Pull one request apart, because the gateway acts on each piece. A request has a method and a URL (the verb and the noun), a set of headers (metadata — who you are, what format you want, your subscription key), and often a body (the data itself, usually JSON). The response answers with a status code, its own headers, and its own body. When 38d rewrites a header, validates a token, or strips an internal field, it is reaching into exactly these slots.
The agreement about what those slots will contain — which operations exist, what each expects, what each returns — is the contract, and its written form is an OpenAPI specification (you will still hear the old name, Swagger). An OpenAPI document is a machine-readable menu: a YAML or JSON file listing every operation, its parameters, and its response shapes. It matters enormously to this track for one reason — APIM can import it and build the whole API model for you, instead of you typing operations by hand. The spec is also what generates the interactive documentation a partner reads in 38e's developer portal.
- API contract
- The promise an API makes about its operations, inputs, and outputs — the shape callers may depend on. OpenAPI is that promise written down in a form both humans and tools can read; breaking it silently is the sin the whole back half of this track guards against.
You met this file already: Class Sixteen's REST APIs & ARM is where Azure's own contracts and the request/response model were introduced, and the /swagger/ endpoint in this site's own footer is an OpenAPI document for CAMPUX's API. This part is that lesson turned toward the consumer's side of the counter.
Why a gateway becomes inevitable
Now the bridge to the rest of the track. A single API with one caller needs no gateway; the contract lives in code and the two sides move together. But an API is a promise, and the day a stranger relies on it, four problems arrive that the backend is a bad place to solve. Who is calling — the request needs a credential in a header, and you need to identify each caller separately. How often — a caller with no throttle can take the service down, and the 429 has to come from somewhere. Where is the real address — the moment partners know the backend's URL, your ability to move, protect, or replace it is gone. Which version — the contract will change, and strangers cannot all update on the same Tuesday.
Every one of those is a property of the request, not the application — which is why they belong at a door that reads requests, not inside the kitchen. That door is API Management, and the rest of this class builds it. You now have the language it operates in: verbs, status codes, headers, bodies, and the contract that governs them. Part B puts the door itself on the wire.
The catalog was already an API
Before any gateway, Campux's storefront already talks to its own catalog service over HTTP: the website calls GET /products to list goods and GET /products/{id} for one item's detail and stock. Nobody called it an API, but it is one — resources with addresses, standard verbs, JSON bodies, and a 404 when an SKU is discontinued. The catalog team even has an OpenAPI file, half-forgotten, generated by their framework.
When the partner request lands, the temptation is to treat "expose the catalog to partners" as a new build. It is not: the API exists, the contract exists, the spec exists. What is missing is everything around the request — identifying each partner, limiting them, hiding the backend, versioning the contract for outsiders. That is the whole realisation this part is for: the API was never the hard part. The front desk is. And the forgotten OpenAPI file is about to become the most useful document Campux owns, because 38c imports it in one step.
Reading a failing integration in ninety seconds
A partner emails that your API is down. You ask for one thing: the status code. They say 403. In ninety seconds you know it is not down at all — their credential is valid (or it would be 401) but they are calling an operation their product does not include, or their subscription lapsed. No log dive, no war room: the three digits told you whose problem it is and roughly where. That fluency — verb, code, header, body — is unglamorous and is exactly what separates the engineer who owns integrations from the one who fears them.
Examination
Four drills, then two situations. The situations have no marking scheme — write your answer before you reveal the reasoning, or the exercise is worthless. Nothing is stored; this is between you and the page.
B — DELETE is idempotent, so a retry is safe. Removing item 42 twice leaves the cart in the same state as removing it once: gone is gone. The three POSTs are the trap, and they are not equally dangerous by accident — a retried POST /orders is a duplicate order, a retried POST /payments is a double charge, and a retried notification is a second buzz on someone's phone. This is why the safe/idempotent columns of Table 1 are not trivia: they decide whether a retry policy — in the client, or in the gateway's backend policy in 38d — is a resilience feature or a way to bill a customer twice. The senior habit: before you enable any automatic retry, ask which verb it repeats.
403 — known caller, not allowed. The key was valid, so identity succeeded; 401 is wrong because 401 means the gateway never learned who they were. The distinction is the whole of authentication versus authorization: 401 is I don't know you, 403 is I know you and the answer is no. Confusing them sends a partner on a wild goose chase — a 401 makes them re-check their key when the real fix is a product change, and a 403 makes them ask for permissions when their key has actually expired. C (404) leaks less but lies about the reason; some APIs deliberately return 404 instead of 403 to avoid confirming a resource exists, which is a security choice, not the default. D (400) blames the request's shape, which was fine. Reading these three apart is the ninety-second debugging skill from the On-the-job box.
Resources-by-URL, statelessness, and safe GETs. Each is what makes the gateway possible: predictable nouns and verbs let it route without understanding your app, statelessness lets it sit in the middle and lets any backend answer the next call, and safe GETs are what it may cache in 38d. The two rejects describe the opposite of REST. Per-caller server sessions break statelessness — now the middle box has to be sticky and a backend cannot be swapped freely, which is the fragility Class 13 warned about. And custom verbs per action are the RPC style REST replaced: they hide the operation inside the URL where a gateway cannot read the intent, so throttling "reads" versus "writes" becomes impossible. The pattern to keep: REST's constraints are not aesthetics, they are what let anything sit in front of the API.
# catalog API — design notes
1. GET /products and GET /products/{id} to read the
catalog and one item.
2. Use GET /products/{id}/delete to remove an item,
so it's easy to trigger from a browser link.
3. Return 201 with the new item's URL when a POST
creates a product.
4. Return 429 with a Retry-After header when a caller
exceeds their rate limit.
Line two — a destructive action hidden behind a GET. GET is defined as safe: no side effects. Put a delete behind it and you have lied to every piece of infrastructure that trusts that promise — a browser prefetch, a search crawler, or the gateway's own response cache can now wipe products by merely reading a link, and a caching policy in 38d would cheerfully store a "success" for a destructive call. The fix is DELETE /products/{id}, where the verb tells the truth. The distractors are all correct behaviour: a collection and its items sharing /products is exactly right (A), 201 Created with the new resource's URL is the textbook POST reply (C), and 429 with Retry-After is precisely how a rate limit should answer (D — it is what half of 38d exists to produce). The habit: whenever a verb and its side effect disagree, trust the side effect and change the verb.
Concede the grain of truth first. POST-everything does "always work" in the narrow sense that a POST is allowed to do anything, so nothing you build on it is technically wrong. Agreeing to that keeps the conversation about consequences rather than correctness, which is where you win.
Then price what the disguise costs, in gateway terms. The moment a read is a POST, the gateway can no longer tell reads from writes — and every capability that depends on that distinction quietly dies. It cannot cache the catalog, because POSTs are not safe to cache, so the backend serves every browse from scratch. It cannot let clients safely retry, because a retried POST might duplicate. It cannot route or throttle "expensive writes" differently from "cheap reads." You have not simplified the API; you have blinded the front desk this whole track is about to build, and you will spend 38d fighting the consequence.
Close by making the right way the easy way. The correct design is not more work: GET to read, POST to create, DELETE to remove — the verbs are free and they carry meaning the whole estate reads for you. The sentence that lands: the verb isn't decoration, it's the one word the gateway, the cache, and the retry logic all read — make it lie and they all go blind.
Lead with the image, not the acronym. "An API is a menu. You order from it without ever entering the kitchen — you say what you want in a form the waiter understands, and food comes back. The restaurant can change chefs, suppliers, the whole kitchen, and your dinner is unaffected, because the menu is the only promise you rely on." A non-coder has now understood the single most important property: an API hides how, and exposes what. That they can follow it is the point — the interviewer is testing whether you understand it well enough to make it simple.
Then turn the menu into the contract. "The written contract — we call it OpenAPI — is the menu printed and signed. It lists every dish, what you have to say to order it, and what arrives. It matters because the moment someone outside my company builds their business on my menu, I can't quietly change it. If I remove a dish they order every morning, their kitchen fails, not mine — and they will not have found out until it breaks." That connects the abstraction to money and to other people's mornings, which is the register this bootcamp rewards.
Close on why the written form earns its keep. "Because it is written and machine-readable, tools can act on it: my gateway builds itself from it, my partners get generated documentation from it, and I can diff two versions to see whether a change breaks the promise before I ship it. The contract turns 'don't break the API' from a hope into something a computer can check." That final sentence tells the interviewer you see the contract not as paperwork but as the thing that makes the entire rest of API Management possible — which is exactly why this track starts here.
Five things worth carrying out of this part
- An API is a contract between two programs — a menu that exposes what you may ask and hides how it is answered. Everything in Azure, and everything this track fronts, is one.
- REST names resources by URL and acts on them with standard verbs. GET reads (safe, cacheable), POST creates (unsafe, not idempotent), PUT replaces, PATCH edits, DELETE removes — and safe/idempotent decide whether a retry is free or dangerous.
- Status codes sort by first digit: 2xx worked, 3xx go elsewhere, 4xx your fault, 5xx the server's. 401 vs 403 is authentication vs authorization; 429 is the sound a gateway makes doing its job.
- A request is a method, a URL, headers, and a body; the response is a status, headers, and a body. The gateway reads and can rewrite every one of those slots — every policy in 38d is a rule about one of them.
- The contract's written form is OpenAPI. It matters because tools act on it: the gateway imports it, partners get docs from it, and a diff can catch a breaking change before it ships.
- REST is the dominant style this part teaches, but not the only one a gateway fronts. GraphQL sends every call as one POST and moves the "which fields" question into the request body; gRPC uses HTTP/2 and binary payloads; older SOAP APIs wrap everything in XML envelopes. APIM can front all of them, but the caching, verb-routing, and retry reasoning here is cleanest on REST — which is why it, and the AZ-400 outline, start there. ↩
- "Idempotent" has a precise edge worth the footnote: PUT and DELETE are idempotent by the HTTP spec, but only if your backend implements them that way. A DELETE that returns 404 on the second call instead of 204 is still idempotent in state (the thing is gone) even though the status differs — and a POST can be made idempotent with a client-supplied idempotency key, which is how payment APIs make retries safe. Treat the table as the default, not a law of physics. ↩