Sending request parameters
There are all sorts of options that can be sent to an API endpoint and figuring out where to put things can be tricky at first.
Let’s look at the four options.
Path Parameters
Given the URL /collections/shoes/products?sort=date&size=10&color=red the
“path” is the /collections/shoes/products, and slashes separate bits of a URL,
some of which are static and some are variables. In this example shoes is a
variable that could be swapped for another collection on the e-commerce store,
e.g: hats.
There is no concept of a “path parameter” in HTTP RFCs, this is purely a convention, but it’s common as API design terminology.
Query Parameters
That same URL example has “query parameters” defined in the query string:
/collections/shoes/products?sort=date&size=10&color=red, which starts at, and
includes, the ?: ?sort=date&size=10&color=red.
This string can be parsed into [sort: 'date', size: '10', color: 'red'].
These options generally cover filtering, sorting, and pagination.
- Filtering:
?brand=Samsung&inStock=true. - Sorting:
?sort=date&sortBy=desc. - Pagination:
?page=2&limit=10or?cursor=abc123.
They should never be used for anything destructive, or break the rules of the method they’re being used in (e.g. modify data on a GET), but they can have other uses.
Some people use query strings for other purposes like changing the response data
that will come back, like using GET /articles/123?include=comments to squeeze
a bunch of comments data into the article response. This was considered best
practice in early 2010s but much like “image sprites” and “CSS combination” it’s
now generally a bad practice, aided with improvements to HTTP/2 and HTTP/3.
Everything is a string because the whole URL is a string. Typed languages often
allow you to define types that these values should be converted to, so size=10
can become 10 instead of "10", and inStock=true can become a proper true
instead of a literal string "true".
HTTP Headers
HTTP Headers (also known as HTTP Header Fields) are metadata for a request, that can have a wide variety of impacts across the API and various network components along the way. You may have spotted this in the same code above.
Content-Type: application/jsonThat lets the API know that the message contains JSON.
Accept: application/jsonThat lets the API know we’d like JSON back too, if it can, we’re ready for it.
If-Modified-Since: Wed, 30 Oct 2024 10:58:31 GMTOnly bother returning any data if its changed since then, otherwise just let us know it’s the same and save server resources.
These standard request headers are defined by Internet Engineering Task Force
(IETF) in RFC 9110
You can define your own headers, but it’s important to avoid replicating
standard functionality with custom headers. People do odd things like the
MyCompany-API-Key when they could use the standard Authorization header.
Various network components like cache proxies will know what to do with an
Authorization and will respond accordingly (changing the way caching works to
avoid leaking data to others), but you will need to somehow teach those network
components what to do with a custom MyCompany-API-Key.
Custom headers should be limited to handy but non-vital information, like trying out a new beta feature hiding behind a feature flag.
Acme-Feature-Toggle: beta-feature=trueFor everything else, there’s the request body.
Last updated on