Learning REST APIs in 15 Minutes

REST APIs are a way for programs to communicate with each other using URLs. It is an Application Programming Interface that follows the representational state transfer (REST or RESTful) software architectural style. A developer sets up an API on a server and allows clients to talk to it.

A practical example of this is when you go to YouTube to search for a funny cat video. When you write a search message and press enter, your browser sends a request to YouTube’s servers containing your search string. Their server processes that information and responds with a list of videos. The request and response model of communication is the core of the REST architecture. Because of their relative simplicity and versatility, REST APIs have become the de-facto way of transferring data on the internet.

Structure of a Request

A REST API request consists of four components

  1. An endpoint
  2. A method
  3. Headers
  4. A body

Endpoints

Every API will have a root URL, for example, https://api.github.com/ for Github's public API. An endpoint is an addition to the root URL where the server accepts requests. For the GitHub API, there is a /users endpoint that responds with a list of users. When added to the root URL to form the full path we get https://api.github.com/users. Try opening that URL in a browser and you will see that you get a response as raw JSON. In addition to pointing to certain functionality of the server, endpoints can also be used to send parameters. There are two ways to do this, path parameters and query parameters.

A path parameter has the format https://api.github.com/users/{username}. When filled in, it will look like a unique endpoint, but the server will interpret part of the URL as a variable. For this endpoint, the parameter enclosed in curly brackets can be replaced by a username to get some information about that user, such as their name, number of repositories, and bio.

Query parameters allow you to send key-value items in your request URL. Unlike path parameters, they have a special syntax. They always begin with a question mark (?) and are separated by ampersands (&). An API endpoint with query parameters will look something like this: https://api.github.com/users/octocat/followers?page=1&per_page=1

Methods

Most APIs use HTTP methods to communicate which type of functionality the request will have. The endpoint can have one or more methods. Each method implies which type of behavior the request will have, but it is up to the API developers to follow these rules. The methods themselves do not have any inherent behavior. In total, there are nine HTTP methods, but four of them are much more common than the rest, so we will focus on these. They are:

  • GET: Used to request data from the server. GET methods should have no additional effect on the system.
  • POST: Used to add new data to the server. Often causing a change in state or side effects.
  • PUT: Used to update data on the server.
  • DELETE: Used to request the deletion of a resource on the server

Headers

Headers are a way to pass additional data with an API call. A header consists of a key and a value, separated by a colon (:). For example:

"Content-Type: application/json"

They have many applications, for example, they can be used to tell which type of data is sent in the request/response, so the receiver can know which parser to use. Other uses include request authentication, sending cookies, identifying clients, and more.

Body

The last component of a request is the body, which contains the data of the request. A body is typically required by POST and PUT methods, for example, to store or update a database entry. Request bodies can contain many different types of data, such as JSON, HTML or binary files. It is common practice to use the “Content-Type” header to denote which kind of data is being sent in the body.

Responses

When a server receives a request, it will process it and return a response. A response has headers and a body, just like a request does. But it also has a status code, that says what happened with the request. The status codes range from 100+ to 500+. Each status code has its own meaning, and they are grouped such that the first number in each status code has a special meaning.

  • 100s: Informational responses
  • 200s: Successful responses
  • 300s: Redirection responses
  • 400s: Client error responses
  • 500s: Server error responses

Some common examples include 404: Not Found, 200: OK, and 500: Internal Server Error, at least one of these you have likely seen before, and now you know where it comes from.

Using an API

Now that you know what a request and response look like, let us use of this knowledge to make some requests to a public API. To make requests, you will need an HTTP Client. Luckily, they are available in most programming languages. Some common ones are curl in bash, requests in python, and AJAX in JavaScript.

For our example, we will again use the GitHub API that has the root URL https://api.github.com. Let us use it to find some information about a user and then see how we can authorize our own account and create a new repository.

We will make the requests using the requests package in python. Because requests is not part of the python standard library, we must first install it:

$ pip install requests

We can use the requests.request function to make our request. Let us make a GET request to get some information about the octocat user, which is an account for Github's mascot. The request function has two mandatory arguments; The method to use and the URL to send the request to. On Github's API documentation https://docs.github.com/en/rest/reference/users we can find that there is an endpoint /users/{username} that provides public information about an account. Here is the code required to make the request:

response = requests.request(
"GET",
"https://api.github.com/users/octocat"
)
response.json()

When we run the code we get this output:

{
'login': 'octocat',
'id': 583231,
'node_id': 'MDQ6VXNlcjU4MzIzMQ==',
'avatar_url': 'https://avatars.githubusercontent.com/u/583231?v=4',
'gravatar_id': '',
'url': 'https://api.github.com/users/octocat',
...'followers': 3714,
'following': 9,
'created_at': '2011-01-25T18:44:36Z',
'updated_at': '2021-04-22T14:27:39Z'
}

The response.json() method converted the response message into a dictionary for us and we can see that we get a good amount of information about this user.

We have talked briefly about how GET requests are considered safe, so we can use them without first authorizing ourselves. POST requests, on the other hand, have lasting effects on the server. Therefore, you must often authorize requests with other methods, to prove that you are permitted to perform the requested action. The most common way to authorize a request is to use headers.

For the GitHub API, you must first generate a personal access token to use as a unique identifier for your account that you can pass in the header. To do this, follow the steps outlined in this guide https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token. Make sure that the token has permissions to create a repository. Once finished, copy the token somewhere safe, as you will not be able to see it again. For this example, save your token as a constant TOKEN.

To find which endpoint we should use to create a repository, we once again refer to the documentation https://docs.github.com/en/rest/reference/repos#create-a-repository-for-the-authenticated-user, where we find the endpoint /user/repos that can have one or more body parameters, with name being required. We can make a new repository with a description with this request:

response = requests.request(
"POST",
"https://api.github.com/user/repos",
json={
"name": "rest-api-tutorial",
"description": "This repository was created as part of a tutorial on REST APIs"
},
headers={"Authorization": f"token {TOKEN}"},
)
print(f"Response: {response.status_code} - {response.reason}")

Here we use the JSON parameter of the request function, which converts a dictionary to JSON and adds the “Content-Type: application/json” header. We must also add an authorization header so that GitHub can know that we have permission to make this request. When we run the code, we get this:

Response: 201 - Created

We get a 200s response, which means that the request was successful.

Now you have seen what a REST API is and how requests and responses are structured. You have also seen how to consume an API using the requests client in python to make GET and POST requests. It is important to remember that a REST API is nothing more than an API that follows the REST architectural style. It is not set in stone, instead, it is up to each developer to follow the rules set by REST to the best of their ability. Therefore, it is important to read the documentation of the API you are going to use because no two APIs are the same.

The next step can be to create an API for your own application. Daeploy offers one of the easiest ways to convert your python code into REST API applications and deploy them as microservices. Click here to learn more and get started.

Daeploy helps you to create APIs out of your existing #python code and deploy it as web services. Get started now!