Register to get access to free programming courses with interactive exercises

HTTP API Example HTTP API

HTTP APIs can vary significantly, both in terms of the use of HTTP capabilities and in terms of the internal structure of the data passed through the API. We'll talk about this in more detail in future lessons, but for now consider a popular HTTP API variant built on the following rules:

  • Data is passed in JSON format
  • A different URL is used for each data set

This isn't the only way to organize the HTTP API, but it is one of the most common. For example, let's take a service created specifically for experimenting with APIs https://dummyjson.com/. It includes pretend data that you can play around with.

The service documentation describes resources and entities, information about which we can get via APIs. Below is a non-exhaustive list:

URL Description
/posts List of posts
/comments List of comments on posts
/users List of users
/todos Task list

Every link that we get data through in the HTTP API is called an endpoint. For example, to get the list of users, you need to download https://dummyjson.com/users. It can even be opened in a browser. The response will return this text (incomplete version):

{
    "users": [
        {
            "id": 2,
            "firstName": "Sheldon",
            "lastName": "Quigley",
            "maidenName": "Cole",
            "age": 28,
            "gender": "male",
            "email": "hbingley1@plala.or.jp",
            "phone": "+7 813 117 7139",
            "username": "hbingley1",
            "password": "1@#4asdfSDF!WER",
            "birthDate": "2003-08-02",
            "image": "https://robohash.org/doloremquesintcorrupti.png?size=50x50&set=set1",
            "bloodGroup": "O+",
            "height": 187,
            "weight": 74,
            "eyeColor": "Brown",
            "hair": {
            "color": "Blond",
            "type": "Curly"
        },
        {
            ...
        }
    ],
    "total": 100,
    "skip": 0,
    "limit": 30
}

The data we see here isn't real, but it's good enough for us to test. In a real API we would still be required to confirm access, because we can't give this data to just anyone. In addition, the password is displayed here, which doesn't happen in real life.

The format in which the data is passed is called JSON. Let's elaborate on that. A format is a way of describing data in which it can be "packed" (serialized) and from which it can be "extracted" (deserialized). We also need to think about serialization and deserialization, which we do when we need to pass data from a program to somewhere outside, for example, another program. This is due to the fact that data within languages is represented in a way that's unique to that language, and even to that particular version of the given language. Therefore, we use more universal formats to transfer data.

In the case of the HTTP API, the service that provides it retrieves the data from the repository, generates JSON, and passes it out. This JSON can then be read by any program that can support JSON, which any program can in the modern world. JSON support is often implemented in the programming languages themselves.

JSON is just text. It has a clear structure that can be traced visually. Indentation, spaces, and hyphenation are irrelevant to JSON. The example above might also look like this:

{"users":[{"id":2,"firstName":"Sheldon","lastName":"Quigley","maidenName":"Cole","age":28,"gender":"male","email":"hbingley1@plala.or.jp","phone":"+78131177139","username":"hbingley1","password":"1@#4asdfSDF!WER","birthDate":"2003-08-02","image":"https://robohash.org/doloremquesintcorrupti.png?size=50x50&set=set1","bloodGroup":"O+","height":187,"weight":74,"eyeColor":"Brown","hair":{"color":"Blond","type":"Curly"}}],"total":100,"skip":0,"limit":30}

One might ask, how this different from transferring data in HTML. HTML is not a data format. HTML is a markup language that generates text for browsers to display as a web page. HTML doesn't involve working with data contained within it. Theoretically, it can be done, but in practice it'll be very difficult.

JSON is not the only data format. Before it, XML was a popular format and it's still quite common now:

<?xml version="1.0"?>
<Recipe>
   <Name>Lime Jello Marshmallow Cottage Cheese Surprise</Name>
   <Description>
     My grandma's favorite (may she rest in peace).
   </Description>
   <Ingredients>
      <Ingredient>
         <Qty unit="box">1</Qty>
         <Item>lime gelatin</Item>
      </Ingredient>
      <Ingredient>
         <Qty unit="g">500</Qty>
         <Item>multicolored tiny marshmallows</Item>
      </Ingredient>
   </Ingredients>
   <Instructions>
      <Step>
         Prepare lime gelatin according to package instructions
      </Step>
      <!-- And so on... -->
   </Instructions>
</Recipe>

XML, although similar to HTML, has a different function. XML is a data format like JSON, it's not designed for output.

JSON structure

Data in JSON format is stored inside objects. An object is a piece of data bounded by curly brackets, within which keys and their values are given:

{ "id": 3, "hasBranches": true, "name": "Hexlet", "country": "Finland" }

Keys in JSON are always wrapped in quotes. Values can be numbers, boolean values, strings and null:

  • 1, 3, 2.5
  • true, false
  • "one", "two"

And then there are arrays:

{ "courses": ["php", "ruby", "python"] }

The whole of JSON can only be one array:

["one", "two", "three"]

Objects can be nested in other objects:

{ "id": 3, "hasBranches": true, "name": "Hexlet", "address": { "country": "Finland", "city": "Helsinki" } }

And into arrays:

{ "courses": [{ "id": 1, "name": "php" }, { "id": 2, "name": "javascript" }] }

Metadata

If you look at the /users response structure, you see that the list of users is passed as an array inside an object with additional parameters.

{
    "users": [],
    "total": 100,
    "skip": 0,
    "limit": 30
}

Why do that, why not just give the array of users right away?

[{ ... }, { ... }]

The answer here is very simple. In addition to the data itself, it's often necessary to transfer some metadata (data about the data), such as the total number of users. If we had an array, it would be impossible to add this information without changing the structure, going from array to object. Objects allow you to add new data while maintaining backward compatibility in the structure, i.e., without breaking it. All you have to do is add a new key to the top level.

Pagination

What if there's a lot of data? For example, there are hundreds of thousands of users on Hexlet. JSON with that much data would be absolutely massive. To solve this problem, we have pagination. Data is not given as a whole, but in small sets. We can see pagination everywhere on the Internet, remember, for example, the search results in Google, where the result is millions of pages, but only the first 10 are shown, and the rest is hidden behind other pages.

In the API we work with, by default, 30 results are given, as you can see in the JSON that was returned.

{
    "users": [],
    "total": 100,
    "skip": 0,
    "limit": 30
}

How do you get the second 30 people in that case? By adding the skip: https://dummyjson.com/users?skip=30

{
    "users": [],
    "total": 100,
    "skip": "30",
    "limit": 30
}

Data limitation

Suppose we don't need all the data, but only some of it. To do this, our HTTP API has a select request parameter: https://dummyjson.com/users?select=firstName,gender

{
     "users": [
        {
            "id": 1,
            "firstName": "Terry",
            "gender": "male"
        },
        {
            "id": 2,
            "firstName": "Sheldon",
            "gender": "male"
        },
        {
            "id": 3,
            "firstName": "Terrill",
            "gender": "male"
        }
    ]
}

Single resource

/users returns a list of users. If we need one user, we need a different endpoint /users/{id}. This endpoint is called dynamic because it has a part that changes. We replace {id} with the ID of the user whose data we want to retrieve. For example: https://dummyjson.com/users/9

{
    "id": 9,
    "firstName": "Demetrius",
    "lastName": "Corkery",
    "maidenName": "Gleason",
    "age": 22,
    "gender": "male",
    "email": "nloiterton8@aol.com",
    "phone": "+86 356 590 9727",
    "username": "nloiterton8",
    "password": "HTQxxXV9Bq4",
    "birthDate": "1971-03-11",
    "image": "https://robohash.org/excepturiiuremolestiae.png?size=50x50&set=set1",
    "bloodGroup": "A+",
    "height": 170,
    "weight": 97.1,
    "eyeColor": "Green",
}

Nested resources

In the services we're looking at here, users have posts. What if we want to see not the entire list of /posts, but the posts of a particular user? How do we do that? In this case, we'll use nested resources: https://dummyjson.com/users/3/posts. This endpoint will return all of the user's posts with the ID 3:

{
    "posts": [
        {
            "id": 58,
            "title": "Balloons are pretty and come in different colors",
            "body": "Balloons are pretty and come in different colors, different shapes, different sizes, and they can even adjust sizes as needed. But don't make them too big or they might just pop, and then bye-bye balloon. It'll be gone and lost for the rest of mankind. They can serve a variety of purposes, from decorating to water balloon wars. You just have to use your head to think a little bit about what to do with them.",
            "userId": 3,
            "tags": [
                "american",
                "crime",
                "magical"
            ],
            "reactions": 9727
        },
    ],
    "total": 4,
    "skip": 0,
    "limit": 4
}

The same principle is applied to all other resources:

URL Description
/users/{id}/posts List of a given user's posts
/users/{id}/comments List of the user's comments
/users/{id}/todos List of the user's tasks

Let's look at the big picture

We've taken apart one particular HTTP API, which has its own rules for interacting with endpoints. In other HTTP APIs, it'll be different, but it's up to each developer to decide. What remains unchanged is that we're working through HTTP and using its features.


Hexlet Experts

Are there any more questions? Ask them in the Discussion section.

The Hexlet support team or other students will answer you.

About Hexlet learning process

For full access to the course you need a professional subscription.

A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.

Get access
130
courses
1000
exercises
2000+
hours of theory
3200
tests

Sign up

Programming courses for beginners and experienced developers. Start training for free

  • 130 courses, 2000+ hours of theory
  • 1000 practical tasks in a browser
  • 360 000 students
By sending this form, you agree to our Personal Policy and Service Conditions

Our graduates work in companies:

<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.bookmate">Bookmate</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.healthsamurai">Healthsamurai</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.dualboot">Dualboot</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.abbyy">Abbyy</span>
Suggested learning programs
profession
Development of front-end components for web applications
10 months
from scratch
Start at any time

Use Hexlet to the fullest extent!

  • Ask questions about the lesson
  • Test your knowledge in quizzes
  • Practice in your browser
  • Track your progress

Sign up or sign in

By sending this form, you agree to our Personal Policy and Service Conditions
Toto Image

Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.