Skip to main content

Your first API

This page takes you through the three jobs almost every API needs, in one sitting: publish a backend through the gateway, ask every client for an API key, and limit how often a client may call. Each part ends with a request you send and the answer to expect. Do the parts in order; each one builds on the last.

Every step is also a guide of its own, linked at the end of each part, with more detail and the other choices you could make.

Before this session​

  • An environment connected to a running cluster, from First sign-in and the first environment, and a role in it from People and access.

  • A backend to publish, reachable from the gateway nodes. This page uses two backend nodes of an orders service, 10.0.1.10:8080 and 10.0.1.11:8080. One is fine; fill in one row where the page fills in two.

  • The address of your gateway. In the console it is the first part of the Address line on a route's Overview tab, api.example.com in this page's examples; replace it in every request below, port included when the line carries one. That line is built from the environment's Gateway URL, which a Platform administrator sets to whatever the gateway answers on, HTTP or HTTPS, with its certificate in place or not yet.

  • A terminal with curl. The requests call /orders/42. The -L in them makes curl follow a redirect, for a gateway that sends HTTP clients to HTTPS; where the address is already the final one, it does nothing.

  • The Editor or Environment administrator role in this environment. If you do not know your role, ask whoever gave you access.

In this session​

  1. Publish the backend through a route, as Route requests to a backend does in full.
  2. Ask every client for an API key, as Require an API key and Give a client its key do in full.
  3. Limit how often a client may call, counted per consumer here; Limit requests on a route counts per client address, and Limit one client wherever it calls follows one consumer across routes.

The three parts below do these in order, with every console step and the request that checks it.

Part 1: publish the backend​

A route says which requests the gateway takes and where it sends them.

1. Create the route​

In the menu, check the environment switcher at the top shows the environment you mean. Select Routes, then New route.

SectionFieldValue
GeneralNameorders-api
MatchingPaths/orders, press Enter, then /orders/*, press Enter
MatchingMethodsTick GET and POST
TargetChoiceNodes on this route
TargetNodesFirst row: Host 10.0.1.10, Port 8080, Weight 1. Select Add entry. Second row: 10.0.1.11, 8080, 1.

Leave everything else as it is and select Create route. The console opens the route. It is saved like this:

route · as the console saves it
{
"name": "orders-api",
"uris": [
"/orders",
"/orders/*"
],
"methods": [
"GET",
"POST"
],
"upstream": {
"type": "roundrobin",
"nodes": {
"10.0.1.10:8080": 1,
"10.0.1.11:8080": 1
}
}
}

The roundrobin in it is the default Type, which spreads requests over the nodes by their weight.

2. Find the address and send a request​

On the route's Overview tab, the Address line shows the address clients call, the gateway host followed by each of the route's paths. Send a request several times, then once as a DELETE, a method the route does not list.

curl
curl -i -L 'https://<gateway host>/orders/42'
curl
curl -i -L -X DELETE 'https://<gateway host>/orders/42'
Sent several times
Repeated requests are all answered 200, and the two backend nodes share them, as each node's own log shows: the two share the traffic.
Sent as a DELETE
A DELETE, a method the route does not list, is answered 404 Route Not Found: no route takes it.

The backend is published. Anyone who can reach the gateway can call it, which the next part changes.

More on this part: Route requests to a backend.

Part 2: ask every client for a key​

A key lives in a credential of a consumer, which stands for one client. The plugin key-auth on the route reads the key.

3. Create the consumer​

Select Consumers, then New consumer. Set Username to mobile-app, type a Description in your own words, and select Create consumer.

4. Give it a key​

On the consumer's Credentials tab, select New credential.

FieldValue
Credential IDmobile-app-key-2026
Pluginkey-auth
KeyA long random text from a password generator. Keep it; you send it in step 6.

Select Create credential. A credential names one plugin because that plugin decides what the credential holds, a key for key-auth, and only that plugin reads it.

5. Put key-auth on the route​

Select Routes in the menu, open orders-api and its Plugins tab, and select Add plugin at the top right. Open the Authentication category, select key-auth, then Configure. Set Header to x-api-key and turn Hide credentials on. Select Add plugin at the bottom of the panel.

key-auth · as the console saves it
{
"header": "x-api-key",
"hide_credentials": true
}

From now on every request without a known key is refused. On a route that already serves clients, do steps 3 and 4 for every client before step 5.

6. Send a request with the key, and one without​

curl
curl -i -L 'https://<gateway host>/orders/42' \
-H 'x-api-key: <the key you created in step 4>'
With the key
A request whose x-api-key header carries the key of mobile-app is answered 200; the header is removed before the request reaches the backend, which receives X-Consumer-Username: mobile-app instead.
Without a key
A request that carries the key neither in that header nor in the apikey query parameter is answered 401 with {"message":"Missing API key in request"} and WWW-Authenticate: apikey realm="key".
With a key nobody has
A request whose key no credential holds is answered 401 with {"message":"Invalid API key in request"}.

More on this part: Require an API key and Give a client its key.

Part 3: limit how often a client may call​

limit-count counts requests and refuses the ones over a limit. Counted by consumer, each client gets a limit of its own.

7. Put limit-count on the route​

On the Plugins tab of orders-api, select Add plugin. Open the Traffic category, select limit-count, then Configure.

FieldValue
Count100
Time window60, in seconds
Keytype consumer_name. This is the counting key, the value that tells callers apart, not the API key.
Rejected code, under Behavior429
Rejected message, under BehaviorToo many requests, try again in a minute

Select Add plugin.

limit-count · as the console saves it
{
"count": 100,
"time_window": 60,
"key": "consumer_name",
"rejected_code": 429,
"rejected_msg": "Too many requests, try again in a minute"
}

8. Use the limit up​

Send the request from step 6 until the limit is reached. Each answer carries X-RateLimit-Remaining, counting down from 99. A shell loop gets there:

for i in $(seq 101); do curl -s -o /dev/null -w '%{http_code}\n' 'https://<gateway host>/orders/42' -H 'x-api-key: <the key you created in step 4>'; done
Over the limit
Each consumer has 100 requests a minute of its own: once one has used them, its next request is answered 429 with {"error_msg":"Too many requests, try again in a minute"}, while another consumer calling from the same address still gets 200 with X-RateLimit-Remaining: 99.

The second consumer in that answer is one you would create by repeating steps 3 and 4 with another name.

More on this part: Limit requests on a route.

What you should see​

A route your clients call at one address, a client that signs in with a key your backend can see in X-Consumer-Username, and a limit that holds each client to 100 requests a minute. The guides widen each of the three. From here, on your own:

Where this leads​

This is the last session. From here the guides take over, in the order their groups list them. Protect an API takes the client and its key further. Control traffic decides how much each may send and what happens when a backend fails. Shape requests and answers and Serve HTTPS finish the picture. When the API is live, Operate is where you watch it, audit it and run the server.

G8 dev