Javascript - Criando um módulo Ajax com Promises - Parte 3

Já vimos o quanto callback hell é ruim, e como as Promises resolvem o problema. Agora estamos criando nosso próprio módulo Ajax, que retorna Promises done e error para que saibamos exatamente o momento em que a requisição retornou algum resultado.

Como vimos no artigo anterior, após todos os nossos testes estarem passando, é hora de verificarmos se nosso código precisa de um refactory. Como tínhamos algumas duplicidades, criamos um novo método e centralizamos o código para remover a duplicidade.

Mas código limpo não vale apenas para o nosso código final, e sim também para os testes! Isso mesmo! Se você der uma olhada no nosso arquivo de testes tests/test.ajax.js, vai perceber que, em todos os testes, estamos instanciando o objeto Ajax.

Ainda não precisamos de instâncias diferentes, então podemos centralizar tudo em uma única chamada, no início da função describe(), que centraliza os testes de interface, e remover as chamadas dentro de cada teste (funções it()).

Nosso arquivo de testes, tests/test.ajax.js, refatorado, agora está assim:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
describe( 'Test module interface', function() {
var ajax = new Ajax();

it( 'Should have `get` method', function() {
ajax.should.have.property( 'get' );
});

it( 'Should have `post` method', function() {
ajax.should.have.property( 'post' );
});

it( 'Should have `put` method', function() {
ajax.should.have.property( 'put' );
});

it( 'Should have `delete` method', function() {
ajax.should.have.property( 'delete' );
});

it( 'Should `get` method return `done` method', function() {
var getRequest = ajax.get();
getRequest.should.have.property( 'done' );
});

it( 'Should `get` method return `error` method', function() {
var getRequest = ajax.get();
getRequest.should.have.property( 'error' );
});

it( 'Should `post` method return `done` method', function() {
var postRequest = ajax.post();
postRequest.should.have.property( 'done' );
});

it( 'Should `post` method return `error` method', function() {
var postRequest = ajax.post();
postRequest.should.have.property( 'error' );
});

it( 'Should `put` method return `done` method', function() {
var putRequest = ajax.put();
putRequest.should.have.property( 'done' );
});

it( 'Should `put` method return `error` method', function() {
var putRequest = ajax.put();
putRequest.should.have.property( 'error' );
});

it( 'Should `delete` method return `done` method', function() {
var deleteRequest = ajax.delete();
deleteRequest.should.have.property( 'done' );
});

it( 'Should `delete` method return `error` method', function() {
var deleteRequest = ajax.delete();
deleteRequest.should.have.property( 'error' );
});
});

Agora que temos nosso código refatorado, e nossos testes também refatorados, podemos dar continuidade ao módulo o/

Precisamos fazer nosso módulo funcionar de verdade. Como a funcionalidade dele depende de requisições get, post, put e delete, antes de escrever a funcionalidade, e até mesmo antes de testar, precisamos ter um ambiente básico de backend que responda à esses métodos.

Vamos então criar uma API Rest básica, com NodeJS, para que possamos testar a resposta à esses 4 métodos.

Criando a API Rest

Quando falamos sobre como utilizar o Gulp com o connect e o modrewrite foi mostrado um exemplo básico de API Rest. Vamos usar a mesma ideia, só incrementando com os métodos put e delete.

Crie um diretório api na raiz do projeto, e um arquivo chamado app.js dentro desse diretório. E então, vamos para o código da nossa API:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
'use strict';

var connect = require( 'connect' );
var connectRoute = require( 'connect-route' );
var app = connect();

var users = {
joao: { name: 'João da Silva', age: 30 },
maria: { name: 'Maria Firmina', age: 26 },
paulo: { name: 'Paulo Torres', age: 25 }
};

app.use( connectRoute( function( router ) {
function postRequest( req, res, next ) {
res.setHeader( 'Content-Type', 'application/json' );
res.end( JSON.stringify( users[ req.params.slug ] ) );
}

router.get( '/api/users', function( req, res, next ) {
res.setHeader( 'Content-Type', 'application/json' );
res.end( JSON.stringify( users ) );
});

router.post( '/api/user/:slug', postRequest );
router.put( '/api/user/:slug', postRequest );
router.delete( '/api/user/:slug', postRequest );
}));

app.listen( 3000 );

exports = module.exports = app;

A única diferença para o código que fizemos no outro arquivo são os novos métodos e também exportamos a variável app, para que possamos importar em outro arquivo, e subir nosso servidor com o Gulp.

Agora, na raiz do projeto, você precisa instalar os módulos necessários:

1
npm i --save-dev connect connect-route

E já temos nossa API respondendo à todos os verbos que precisamos! :D

Subindo o servidor

Para subir o servidor, vamos adicionar a nossa API à task default do Gulp. No gulpfile.js, altere a task default para ficar assim:

1
2
3
4
gulp.task( 'default', [ 'assets' ], function() {
require( './api/app' );
gulp.watch([ allTestFiles, 'src/ajax.js' ], [ 'test' ]);
});

Lembra que exportamos o app na API, usando exports = module.exports = app? Esse comando vai servir para que possamos usar o require para adicionar o app.js onde quisermos! No nosso caso, ao executar a task default do Gulp, também subiremos nossa API, na porta 3000.

Agora, executando o comando gulp no terminal, você terá os testes rodando, o coverage e também a nossa API Rest, - que pode ser acessado via http://localhost:3000 - para testar os métodos do nosso módulo de Ajax! :D

Para testar a API, você pode utilizar o Postman, por exemplo :)

Agora já temos tudo o que precisamos para ver nosso módulo funcionando! No próximo artigo vamos finalmente fechar com chave de ouro! :D

Se ficou alguma dúvida, comente!

Até lá! :D

Sobre o #1postperday: https://blog.da2k.com.br/2014/12/31/um-post-por-dia/

Tem alguma sugestão para os próximos posts do #1postperday? Deixe ela aqui: https://github.com/fdaciuk/fdaciuk.github.io/issues/1