Isolando o acesso de API's em classes de serviço
Não é incomum aplicações web buscarem e enviarem dados através de uma API. Mas nem tudo é perfeito; durante esse processo a rede pode cair ou o servidor pode estar fora do ar. Dentro de tanta incerteza, nada mais justo do que informar o usuário que houve algum problema.
Vejamos um exemplo que envia um JSON
através do método POST
para uma API hipotética utilizando vanilla JavaScript:
// main.js
// é nóis cangaceiro!
const cangaceiro = { nome: 'Flávio', bando: 'cangaceiros javascript'};
// configurando o header da requisição
const headers = new Headers();
headers.append('Content-Type', 'application/json');
// preparando a configuração necessária para realizara a requisição
const config = {
method: 'post',
headers,
body: JSON.stringify(cangaceiro),
};
// utiliza API Fetch passando o endereço da API e a configuração
fetch('http://seu-dominio/cangaceiro', config)
.then(res => {
// tratamento necessário quando usamos Fetch API
// se não estiver ok, rejeita a Promise lançando uma exceção
if(!res.ok) throw new Error(res.statusText);
// se nenhum exceção foi lançada, retorna a própria resposta
return res;
})
.then(() => alert('Operação realizada com sucesso'))
.catch(err => {
console.log(err);
alert('Não foi possível realizar a operação. Tente mais tarde.');
});
No exemplo anterior, no sucesso da operação a mensagem “Operação realizada com sucesso” é exibida. No fracasso, logamos o valor de err
enviado pelo servidor e exibimos uma mensagem de erro padrão para o usuário. Não faz sentido exibir para ele err
, pois é uma mensagem de baixo nível que só diz respeito ao desenvolvedor.
A abordagem acima deixa a desejar. Vejamos:
- Repetiremos o endereço da API e configuração do cabeçalho em todos os lugares que acessam a API.
- Precisaremos fazer sempre
console.log()
para logar o erro vindo do servidor para o desenvolvedor e precisaremos em seguida fornecer uma mensagem de alto nível de erro para o usuário.
Podemos melhorar o código que vimos com uma ajudinha do paradigma da Orientação a Objetos. Por exemplo, frameworks SPA do mercado como Angular já propõem uma solução para o problema que é isolar toda a complexidade do código em classes de serviço. Por mais que estejamos escrevendo um código vanilla JavaScript nada nos impede de fazermos o mesmo. Boa prática é boa prática independente de framework ou não.
Isolando a API em uma classe de serviço
A classe do serviço centraliza uma série de informações a respeito da API, cabeçalhos e métodos da requisição, inclusive é a responsável por logar e fornecer uma mensagem de alto nível para as operações, livrando o cliente da API de ter que lidar com esses detalhes.
Vejamos um exemplo:
// CangaceiroService.js
class CangaceiroService {
constructor() {
this.domain = 'http://seu-dominio';
this.headers = new Headers();
this.headers.append('Content-Type', 'application/json');
}
cadastra(cangaceiro) {
const config = {
headers: this.headers,
method: 'post',
body: JSON.stringify(cangaceiro)
};
// retorna a Promise
return fetch(`${this.domain}/cangaceiro`, config)
.then(this._handleErrors)
.catch(err => {
// logou erro original
console.log(err);
// lançou uma exceção de alto nível que pode ser exibida para o usuário
throw new Error('Não foi possível realizar a operação. Tente mais tarde');
});
}
// pode ser usados por outros métodos
_handleErrors(res) {
if(!res.ok) throw new Error(res.statusText);
return res;
}
}
Agora, em todo lugar que o serviço for necessário, basta fazermos:
// main.js
const cangaceiro = { nome: 'Flávio', bando: 'cangaceiros javascript'};
new CangaceiroService()
.cadastra(cangaceiro)
.then(() => alert('Operação realizada com sucesso')
.catch(err => alert(err));
Em alert(err)
, teremos a mensagem de alto nível para o usuário e não precisaremos mais nos preocupar em logar o erro original, pois ele já foi logado pelo serviço. Muito mais fácil de ler e de manter do que a versão anterior.
Conclusão
Isolar o acesso de API’s em classes de serviço facilita a manutenção e legibilidade do nosso código. É uma prática aplicada por diversos frameworks do mercado e que podemos utilizar com vanilla JavaScript, inclusive na plataforma Node.js.
Essa e outras práticas você encontra no livro Cangaceiro JavaScript: uma aventura no sertão da programação, 502 páginas.