36
APIS DO JEITO CERTO RAVAN SCAFI

APIs do Jeito Certo

Embed Size (px)

Citation preview

Page 1: APIs do Jeito Certo

APIS DO JEITO CERTORAVAN SCAFI

Page 2: APIs do Jeito Certo

• Ravan Scafi• Web Developer @

Leroy Merlin• Co-organizador do

Meetup do Laravel-SP• twitter.com/ravanscafi

SOBRE MIM

Page 3: APIs do Jeito Certo

SOBRE A APRESENTAÇÃO

• Motivação• Boas práticas na construção de APIs• Lições Aprendidas• Laravel / Lumen ao resgate!

Page 4: APIs do Jeito Certo

APIS REST EM 1 MINUTO

• Recursos como substantivos• Verbos HTTP especificam a ação

$ curl -XGET localhost/api/users/123

Page 5: APIs do Jeito Certo

MOTIVAÇÃO

• Por que escrever uma API?• O que implica ter uma API?

Page 6: APIs do Jeito Certo

# DOCUMENTAÇÃO

Page 7: APIs do Jeito Certo

“Uma API é apenas tão boa quanto sua documentação”

apiary.io

Page 9: APIs do Jeito Certo

SWAGGER / OPEN API

• Uma forma de documentar sua API• Único arquivo swagger.json• Consumível por Humanos e por Máquinas• Swagger-UI: ❤️ ❤️ ❤️ ❤️

Page 10: APIs do Jeito Certo
Page 11: APIs do Jeito Certo

DOCUMENTAÇÃO: DICAS

• Mantenha a documentação próxima ao código• Regras de bom código também valem para

documentação• https://github.com/zircote/swagger-php

Page 12: APIs do Jeito Certo

<?php

class UserController{ /** * @SWG\Post(path="/user", * tags={"user"}, * summary="Create user", * description="This can only be done by the logged in user.", * operationId="createUser", * produces={"application/xml", "application/json"}, * @SWG\Parameter( * in="body", * name="body", * description="Created user object", * required=false, * @SWG\Schema(ref="#/definitions/User") * ), * @SWG\Response(response="default", description="successful operation") * ) */ public function createUser() { } }

Swagger-PHP: Exemplo

Page 13: APIs do Jeito Certo

<?php

$basePath = __DIR__ . '/..';require_once $basePath . '/vendor/autoload.php';

// grabbing info from .env file$beforeEnv = $_ENV;(new Dotenv\Dotenv($basePath))->load();$envVars = array_diff($_ENV, $beforeEnv);

// grabbing info from composer.json file$composerFile = json_decode(file_get_contents($basePath . '/composer.json'));$composerInfo = [ 'COMPOSER_NAME' => $composerFile->name ?? null, 'COMPOSER_DESCRIPTION' => $composerFile->description ?? null, 'COMPOSER_VERSION' => $composerFile->version ?? '0.0.0', 'COMPOSER_LICENSE' => $composerFile->license ?? null,];

// defining grabbed info as constants$desiredConstants = array_filter(array_merge($envVars, $composerInfo));array_map('define', array_keys($desiredConstants), $desiredConstants);

bootstrap/swagger.php

Page 14: APIs do Jeito Certo

{ ... "autoload": { "psr-4": { "App\\": "app/" } }, "scripts": { "api-docs": "swagger app -o public/docs.json -b bootstrap/swagger.php", }}

composer.json

$ composer api-docs

Page 15: APIs do Jeito Certo

# DESIGN

Page 16: APIs do Jeito Certo

VERSIONAMENTO

• Internamente: Semantic Versioning

• Publicamente: só mude versões cheias (v1, v2)

• Evite Breaking Changes (BC) o máximo que conseguir

Page 17: APIs do Jeito Certo

O QUE CONFIGURA UMA BC?

• Remover campos: SIM• Renomear campos: SIM• Adicionar campos: NÃO• Adicionar recursos / endpoints: NÃO

Page 18: APIs do Jeito Certo

PROTEJA-SE COM MUTATORS

• Apresentação e transformação dos dados• Uma “barreira” entre os recursos e a API• Typecasting, relacionamentos

Page 19: APIs do Jeito Certo

<?phpuse Acme\Model\Book;use League\Fractal;

$books = Book::all();

$resource = new Fractal\Resource\Collection($books, function(Book $book) { return [ 'id' => (int) $book->id, 'title' => $book->title, 'year' => $book->yr, 'author' => [ 'name' => $book->author_name, 'email' => $book->author_email, ], 'links' => [ [ 'rel' => 'self', 'uri' => '/books/'.$book->id, ] ] ];});

Transformer: Exemplo

Page 20: APIs do Jeito Certo

NEGOCIAÇÃO DE CONTEÚDO

• JSON é JavaScript, portanto use camelCase• /api/user/123.json, /api/user/123.csv• Recursos embedados: trazer dinamicamente

ou não• Metadados: URI, página atual, count total• Verbo HTTP: override com _method

Page 21: APIs do Jeito Certo

RESPOSTAS

• Padronize campos como: datas, floats, moedas

• Padronize códigos HTTP de resposta• Padronize paginação, metadados, etc.

Page 22: APIs do Jeito Certo

RESPOSTAS

• Faça um “wrap” da resposta em uma chave “data”

• Mostre o erro, ao invés de um código de erro• Nunca exponha exceptions para os usuários• Não reinvente a roda, seja coerente com

padrões

Page 23: APIs do Jeito Certo

AUTENTICAÇÃO

• Baseados em Sessão: NÃO• APIs devem ser sem estados (stateless)• Implementação em mobile é custosa

• Baseados em Token: SIM• OAuth? OAuth2? JWT? Http-Basic?

Page 24: APIs do Jeito Certo

OAUTH VS JWT

• Não são “concorrentes” diretos• É até mesmo possível utilizar os dois em

conjunto• OAuth: concebido para autorização (pseudo

autenticação)• 3-legged vs 2-legged

• JWT: concebido para claims / autenticação

Page 25: APIs do Jeito Certo

Como se parece um token JWT

Page 26: APIs do Jeito Certo

SEGURANÇA

• Evite expor IDs sequenciais• Limite as requisições (Throttling), porém

configurável por conta• Não utilize sessões ou logins por senhas (exceto

em aplicativos próprios)• API somente em HTTPS• Verifique sempre vulnerabilidades com OAuth /

JWT

Page 27: APIs do Jeito Certo

# LARAVEL VS LUMEN

Page 28: APIs do Jeito Certo

LARAVEL VS LUMEN

• Já tenho um app em Laravel: Laravel!• Já tenho um app em Lumen: Lumen!• Vou começar: Lumen!• Use e abuse de Middlewares• Agrupe rotas por versão

Page 29: APIs do Jeito Certo

<?php

$app->group(['prefix' => 'api'], function () use ($app) { $app->group(['prefix' => 'v1'], function () use ($app) { $app->get('users', function () {}); $app->get('products', function () {}); });

$app->group(['prefix' => 'v2'], function () use ($app) { $app->get('users', function () {}); $app->get('products', function () {}); });});

Grupos de Rotas por Versão

Page 30: APIs do Jeito Certo

PACOTES ÚTEIS

• Dingo/API• Zircote/Swagger-PHP• TymonDesigns/JWT-Auth• League - OAuth2 Server• League - Fractal• Ramsey - UUID

Page 31: APIs do Jeito Certo

DINGO/API

• Negociação de Conteúdo• Múltiplos Adaptadores de Autenticação• Versionamento da API• Limitação de Requisições

Page 32: APIs do Jeito Certo

DINGO/API

• Transformers and Formatters de Respostas• Handling de Exceptions e Erros• Requests Internos• Documentação Blueprint

Page 34: APIs do Jeito Certo

LEMBREM-SE: EMPATIA É A CHAVE

Page 35: APIs do Jeito Certo

OBRIGADO!

@ravanscafi