Asynchronous return of some Apis

Asked

Viewed 388 times

11

Why the return of some Apis are exactly the result we want (for example, a JSON) and some others return an object full of functions and objects?

Example API that directly returns the result I want:

function user(id) {
  const users = {
    1: {id: 1, name: 'Lucas'},
    2: {id: 2, name: 'João'}
  };
  return new Promise(resolve => {
    setTimeout(() => resolve(users[id]), 1000);
  });
}

async function exec() {
  console.log(await user(1))
}

exec()

Already others return me an object that contains several things like, for example, body, bodyUsed, headers, ok, redirected, status, statusText, type, url and others.

For example, the Github API:

async function getUserGithub() {
  console.log(await fetch(`https://api.github.com/users/decarvalholucas`))
}
getUserGithub()

Why is it so and what difference do they make to it?

  • Both functions return the same thing: an object. 1) You are returning a "simple" object with the ID properties and the user name; 2) You are returning the object Response, that - to access a json, for example - one of the available methods must be used.

  • Ta, beauty; but the way I showed it there, from the github.. It returns several "patterns" things, I say patterns because most Apis we use return this, so whenever we make another request to pull what we really want, for EXAMPLE, we would have to give a await result.json(). Is that a pattern? It’s always going to be like this return of Apis?

  • The fetch returns a class (Response), which have attributes (ok) and methods json Actually this will depend on the API you are using, if you use FormData, she will have other methods etc.

2 answers

10


TL;DR: The methods in question do not come from the API, but from the object Response which is returned as a promise by fetch. To get the data from the body of the answer, you must use methods such as the json or text, available in the response object prototype (Response).


You are using the API fetch, that returns a Promise that solves in an object Response, which has the methods described in your question.

Therefore, it is not the Github API (or any other) that returns the methods described in the question, because that would not be a valid JSON, since this notation is not able to transfer data as functions or methods.

So the code to follow does not return your API’s JSON, but an object Response:

async function resolveFetch(...params) {
  // O `await` resolve a `Promise` retornada pelo `fetch` no objeto `Response`.
  const responseObject = await fetch(...params);

  // Aqui, `responseObject` é um objeto `Response` (retornado pelo `fetch`)
  // como uma promessa que já se resolveu.
  // Esse objeto possui diversos métodos, como o `json`, `text`, e 
  // propriedades como o `headers`, que te permitem converter o retorno da
  // API a um formato desejado (como o `json`) ou obter informações sobre
  // a resposta da requisição.
  return responseObject;
}

(async () => {
  const result = await resolveFetch('https://api.github.com/users/lffg');
  
  console.log(result instanceof window.Response); // true
})();

Thus, to obtain the value of the body of the answer, you must make use of some of the following methods, available in the prototype of the object Response, who were also listed here:

In your case, as you are dealing with Apis that return a JSON, it is more interesting to work with the json to convert the body of the response into text with JSON "parsed".

So we’re like this:

async function fetchJSON(...params) {
  // Aqui, `resolvedResponse` será um objeto `Response`, que veio da
  // resolução da promessa que o `fetch` retorna.
  const resolvedResponse = await fetch(...params);

  // Abaixo estamos usando o método `json`, presente no objeto `Response`
  // para obter o texto do corpo da resposta e já convertê-lo em JSON:
  const json = await resolvedResponse.json();

  // Podemos retornar o JSON.
  // Agora SIM! É o JSON retornado pela API! ;)
  return json;
}

(async () => {
  const json = await fetchJSON('https://api.github.com/users/lffg');

  console.log(json instanceof Response); // false

  // Notamos abaixo que agora sim se trata de um JSON.
  console.log(json.login); // "lffg"
})();

We can even turn this workflow in a simple diagram:

Diagrama 1

  • Damn that dough! Thank you, Luiz. But I still have a question. From what I see, I have to make the "main request" that is in the endpoint of the API, in the case: https://api.github.com/users/lffg, and, as I need the data in json, I again use the await to return the json itself, await Response.json() When I do this, am I again making another request on that API or is that json already within the first response received? The question is precisely because of this, I will have to do 2 rquests the API to actually get the data I need?

  • No. Only fetch does the request. json is only used to "transform" the body of the response into JSON. :)

  • Ahh, now it makes sense, pardon the "nubisse" hahaha, thank you very much, Luiz! + 50

1

Failed to treat the receipt:

async function getUserGithub() {
  await fetch(`https://api.github.com/users/decarvalholucas`).then(function(response) {
      response.json().then(function(data){
          console.log(data);
        });
    });
}
getUserGithub()

Browser other questions tagged

You are not signed in. Login or sign up in order to post.