Understanding and using REST APIs
You may have seen or heard that modern applications use REST APIs. I'll show you whats behind that 🤔
You may have seen or heard that modern applications use REST APIs. API is the abbreviation for Application Programmable Interface and enables communication between (distributed) systems. REST stands for Representational State Ttransfer. In plain language, this means that all requests are stateless. They therefore form the backbone of communication for modern applications.
Basics
Modern applications are very different from "old" systems, where everything is stored on a server. Which is why the exchange of data is becoming increasingly important. In addition, systems are becoming increasingly separated or distributed and must therefore offer interfaces that enable standardized communication. REST APIs have been introduced for precisely this purpose. Wikipedia defines a REST API as follows:
The purpose of REST is focused on machine-to-machine communication. REST is a simple alternative to similar methods such as SOAP and WSDL and the related method RPC . Unlike many related architectures REST does not encode any method information in the URI, as the URI specifies the location and name of the resource, but not the functionality that the web service offers for the resource. The advantage of REST is that a large part of the infrastructure required for REST (e.g. web and application servers, HTTP-capable clients, HTML and XML parsers, security mechanisms) is already available on the WWW and many web services are REST-compliant per se. A resource can be represented via different media types also representation of the resource called.
Source: https://de.wikipedia.org/wiki/Representational_State_Transfer
However, we will limit ourselves here to communication via HTTP.
How did it used to be?
In the past (up to around 2000/2005), this was partly the case. 2000/2005) it was sometimes the case that the data was projected directly into the HTML on the server (e.g. via PHP) and then delivered directly to the client with the data already filled in. Mobile devices or similar were rare. Machine-to-machine communication was carried out by banks, for example, rather via SOAP, RPC or WSDL (XML).
Here, the direction of communication was usually only unidirectional from the server to the client:
Reloading data was also not (or only rarely) necessary, which is why the websites were quite static.
How is it today?
In the meantime, however, computers are not the only ones consuming data, but also mobile devices (cell phones, cars, etc.) and there are now also apps that need to access data. Communications are also no longer unidirectional but bidirectional, because a lot of data is also reloaded (to reduce First Contentful Paint). A current structure would look (simplified) as follows:
And this is where the REST API comes into play.
What data is transferred with it?
In principle, the APIs can offer all kinds of data, but only textual data and files are actually common.
By textual data, I don't mean a book or something else. No. Here I mean structured data. The JSON standard is now (fortunately 😑) very well established for the exchange of data. It defines how the data should look so that all systems can understand and evaluate it. APIs can also provide files such as images or other formats.
How are APIs structured?
REST APIs are structured according to certain schemes, which makes them easy to address.
In essence, APIs offer certain keywords to define what you want to do. These are based on the HTTP standard methods. There are five of these, which are often used on a daily basis: GET
, POST
, PATCH
, PUT
and DELETE
. This allows all CRUD actions to be mapped.
To illustrate this, let's take a look at the PokéAPI. This can be used to query Pokémon from the service.
Basically, you can say that APIs are always structured as follows:
https://server.com/[eventual version]/{resource}/{id}
A resource is always an entity, e.g. a Pokémon, car, item or user.
There may be deviations due to the API provider. Therefore, please always check your provider's documentation beforehand.
Request data via an API
We would now like to have data about a certain Pokémon. I actually quite like Mew and would now like some data for Mew. All (good) API providers document their API and show you how to use it, sometimes with examples. The PokéAPI is no exception:
The GET
method can be used for this, with which we instruct the server to give us data.
In the PokéAPI documentation we can also find a resource endpoint for this:
HTTP GET https://pokeapi.co/api/v2/pokemon/{id or name}/
This means that we can use the endpoint to query a specific Pokémon with an ID
or a name
.
Normal requests via GET
can also be executed in the browser, as a request for a normal web page is also made via a GET
.
So if we now enter the URL for Pickachu above, we get the following return:
In general, this can also be used to query all Pokémon by simply omitting the ID
or name
parameter (https://pokeapi.co/api/v2/pokemon
):
There is now a small special feature here, but one that all APIs generally have, namely paging.
Page-by-page retrieval of data
If a lot of data is required at once, this naturally puts the API provider's server under load, which can become very large even with a large number of data records. To counteract this, APIs often work with pagings. In other words, the page-by-page return of data.
In the above example of all Pokémons, we can see that there would be a total of 1292 Pokémons. That would be far too many for one request. This is why many APIs (that I have come across so far) also contain corresponding commands for traversing the pages. This is usually done via the query string, to which you can then pass parameters for the page and the number of results. In addition, the next page and the previous page are usually also returned as a link so that the developer does not have to manually "calculate" the current, previous and next page in the code.
A page of the PokéAPI for Pokémons can be retrieved with the following URL:
GET https://pokeapi.co/api/v2/pokemon?offset=20&limit=20
Here there is the offset
as a parameter (the starting point of the page) and a limit (for the number of data to be returned). And so you could now run through all pages.
And if I have to change or delete data?
Here it also depends very much on your API provider whether it supports such actions. You can also read about this in the documentation.
The PokéAPI does not offer any endpoints for changing the data, which is perfectly clear because it is a read database. However, if you actually want to write data, it depends very much on what exactly you want to do.
Create dataset
The POST
method is used to create data. By definition, this creates a new data record for the resource. In order for the POST
to work, you must of course also enter the corresponding data. This is usually done via the BODY
of a request.
In comparison to a GET
, the POST
has a request body that contains the data to be used and must also be sent to the API. As a rule, such requests cannot simply be made via the browser, but should be made using cURL
, Postman
or a programming language of your choice. But a call to add the Pokémon Marfra
could look like this:
HTTP POST https://pokeapi.co/api/v2/pokemon
HTTP PATCH https://pokeapi.co/api/v2/pokemon/{id}
Content-Type: application/json
{
"name": "Marfra"
...
}
Here it is important to note that you specify the format for the body. For JSON, this format would be application/json
.
If everything went well, a new Pokémon has now been created and you will usually receive an ID or an identifier that you can use to make further requests. If not, however, you will get some indication in the return of the request as to why it did not work.
Change dataset
This is similar to creating, except that we also have to specify which Pokémon we want to change. The method used in this case would be PATCH
. It is important that we also have to define which Pokémon we want to edit. This is usually done using an ID, name or other unique identifier.
If we now want to add the Super Nerd
ability to our Pokémon, our request could look like this:
HTTP PATCH https://pokeapi.co/api/v2/pokemon/{id}
Content-Type: application/json
{
"ability": "super nerd"
}
If everything worked, the existing Pokémon Marfra
would now have been changed. If not, however, you will receive some indication in the return of the request as to why it did not work.
It is not necessary to have all the data available for the change; it is sufficient if the body of the request contains the field to be changed. There may also be deviations here that the API provider has defined.
Delete dataset
We can use the DELETE
method for this. In contrast to a POST
or PATCH
, this method does not have a body. We don't need one because we have to identify the resource using the unique identifier. This is where our ID
comes into play again. We could delete our Marfra
Pokémon with the command:
HTTP DELETE https://pokeapi.co/api/v2/pokemon/{id}
Special case PUT
Strictly speaking, there is another case, namely PUT
. It is characterized by the fact that, by definition, it is suitable for updating or replacing a data set with all data. Sometimes this method is also used as an "upsert", which changes the data set, if it exists, as an alternative. However, this depends very much on the API provider.
For PUT
, the entire object to be changed (with the changes) must always be transmitted.
HTTP PUT https://pokeapi.co/api/v2/pokemon/{id}
Content-Type: application/json
{
"name": "Marfra"
"ability": "super nerd"
}
Check status codes
If your API has done everything correctly or something is going wrong, it will tell you (more or less accurately). Here it is important to look at the status codes, which originate from the HTTP standard.
Common status codes would be:
- 200 = OK, resource found and method executed
- 404 = Resource not found
- 5XX = There was a server error
The JSON standard
As you can see, it is quite easy to request data and send data to a system. But let's take a look at the standard that is now widely used for storing, retrieving and transmitting data: JSON
No, it has nothing to do with Jason Statham, even if it is often used as a running gag.
JSON stands for JavaSscript Object Notation which was first specified by Douglas Crockfordt in 1997. There is now also an RFC (Request for Comment) 8259 and an ECMA-404.
The data within a JSON can be nested to any depth and basically consists of the following data types:
- Null value = NULL (empty)
- Boolean value = true/false
- Numbers = negative/positive, decimal as well as integers or with specification of exponents (
e
orE
).E
) - String = "I am a string" (if necessary with escaping via
\
) - Array = Indexed lists starting with
[
and ending with]
)
e.g.[1, 2, 3, 4, 5]
- Object = Comma-divided, unordered lists of properties
e.g.[
\].e.g.{ "name": "value", "number": 1, "values": [ 1, 2, 3, 5, 4] }
All types can be mixed with each other and nested infinitely deep (theoretically). In contrast to XML, it offers far less overhead.
In the JavaScript area in particular, this standard has become the "gold standard" and is also used in part to store files that contain a lot of information and are written and read by programs/applications.
Conclusion
You have now gained a little insight into the world of APIs, JSON and the many ways in which APIs can be consumed and how systems chat with each other nowadays. Have fun "tapping" into APIs and grooving the data 🔥
And, do you already have ideas which APIs you can use or do you even already have your own API? Let me know in the comments 👇