Baixe o app para aproveitar ainda mais
Prévia do material em texto
APIs Eficazes Com PHP Sobre Mim Ravan Scafi Back-end Developer na Leroy Merlin Brasil Co-organizador do Meetup do Laravel SP @ravanscafi API? O que é uma API? Interface é um elemento que proporciona uma ligação física ou lógica entre dois sistemas ou partes de um sistema que não poderiam ser conectados diretamente. (ou porque a gente tá aqui hoje) API REST em 1 Minuto API REST em 1 minuto Cada recurso tem seu próprio URI GET http://meusite.dev/api/users/rscafi API REST em 1 minuto Verbos HTTP indicam a ação GET http://meusite.dev/api/users/rscafi API REST em 1 minuto Diferenciação por IDs GET http://meusite.dev/api/users/rscafi Motivação Por que fazer uma API? E o que isto implica? Documentação Como e por que documentar uma API? “ apiary.io “Uma API é apenas tão boa quanto sua documentação” Swagger / Open API Initiative Uma forma de documentar sua API Swagger / Open API Initiative Único arquivo swagger.json (ou .yml) Swagger / Open API Initiative Consumível por humanos e máquinas { "swagger": "2.0", "info": { "description": "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) (...)", "version": "1.0.0", "title": "Swagger Petstore", "termsOfService": "http://swagger.io/terms/", "contact": { "email": "apiteam@swagger.io" }, "paths": { "/pet": { "post": { "tags": [ "pet" ], "summary": "Add a new pet to the store", "description": "", "operationId": "addPet", "consumes": [ "application/json", "application/xml" "parameters": [ { "in": "body", "name": "body", "description": "Pet object that needs to (...)", "required": true, "schema": { "$ref": "#/definitions/Pet" } } ], "responses": { "405": { "description": "Invalid input" Documentação Mantenha próxima ao código Documentação Revisite periodicamente Documentação Se possível, faça Documentation-First /** * @SWG\Info(title="My First API", version="0.1") */ /** * @SWG\Get( * path="/api/resource.json", * @SWG\Response(response="200", description="An example resource") * ) */ Empatia é a chave Empatia é a capacidade de se identificar com outra pessoa, de sentir o que ela sente, de querer o que ela quer, de apreender do modo como ela apreende etc. Design O que me atentar ao fazer uma API? Versionamento Somente exponha a “versão cheia” (v1, v2) Versionamento Evite ao máximo Breaking Changes NÃO ● Adicionar campos ● Adicionar recursos ● Adicionar endpoints ● Corrigir bugs * O que causa uma Breaking Change? SIM ● Remover campos ● Renomear campos ● Remover recursos ● Remover endpoints Proteja-se com Mutators Representam Recursos da API Proteja-se com Mutators Criam uma barreira entre seus Models e sua API Auxiliam em Typecasting e Relacionamentos Proteja-se com Mutators <?php namespace Api\V1\Transformers\User; use Api\V1\Transformers\TranformerInterface; use DateTime; class UserTransformer implements TranformerInterface { public function transform(User $user) { return [ 'name' => "{$user->firstName} {$user->lastName}", 'email' => $user->getEmail(), 'birthday' => $user->birthday->format(DateTime::RFC3339), ]; } } <?php namespace Api\V1\Transformers\User; use Api\V1\Transformers\TranformerInterface; use DateTime; class UserTransformer implements TranformerInterface { public function transform(User $user) { return [ 'name' => "{$user->firstName} {$user->lastName}", 'email' => $user->getEmail(), 'birthday' => $user->birthday->format(DateTime::RFC3339), ]; } } <?php namespace Api\V1\Transformers\User; use Api\V1\Transformers\TranformerInterface; use DateTime; class UserTransformer implements TranformerInterface { public function transform(User $user) { return [ 'name' => "{$user->firstName} {$user->lastName}", 'email' => $user->getEmail(), 'birthday' => $user->birthday->format(DateTime::RFC3339), ]; } } <?php namespace Api\V1\Transformers\User; use Api\V1\Transformers\TranformerInterface; use DateTime; class UserTransformer implements TranformerInterface { public function transform(User $user) { return [ 'name' => "{$user->firstName} {$user->lastName}", 'email' => $user->getEmail(), 'birthday' => $user->birthday->format(DateTime::RFC3339), ]; } } <?php namespace Api\V1\Transformers\User; use Api\V1\Transformers\TranformerInterface; use DateTime; class UserTransformer implements TranformerInterface { public function transform(User $user) { return [ 'name' => "{$user->firstName} {$user->lastName}", 'email' => $user->getEmail(), 'birthday' => $user->birthday->format(DateTime::RFC3339), ]; } } <?php namespace Api\V1\Transformers\User; use Api\V1\Transformers\TranformerInterface; use DateTime; class UserTransformer implements TranformerInterface { public function transform(User $user) { return [ 'name' => "{$user->firstName} {$user->lastName}", 'email' => $user->getEmail(), 'birthday' => $user->birthday->format(DateTime::RFC3339), ]; } } Negociação de Conteúdo Como ter uma comunicação eficiente com os usuários? JSON, XML, CSV? Negociação de Conteúdo Trazer Relacionamentos e Recursos Embeddados? Negociação de Conteúdo Metadados: URI, página atual, contagem total Negociação de Conteúdo Use cabeçalhos HTTP quando relevante Negociação de Conteúdo Respostas Como passar as informações corretas aos usuários? Padronize códigos HTTP de resposta Respostas Padronize campos de datas, floats, moedas Respostas Padronize Metadados Respostas Não reinvente a roda Respostas { "data": { "name": "John Doe", "email": "johndoe@gmail.com", "birthday": "17/09/2016" } } Faça um “wrap” da resposta { "name": "John Doe", "email": "johndoe@gmail.com", "birthday": "17/09/2016" } { "errorCode": 451942, "errors": [ "Username must contain only letters and numbers", "E-mail is required" ] } Mostre a descrição do erro, não somente um código { "error": 451942 } { "errorCode": 500, "errors": [ "Unknown error occurred. Check you input or try again later." ] } Nunca exponha Exceções para o Usuário { "exception": “NullPointerException” } Autorização e Autenticação Como identificar meus usuários e suas permissões? Autorização e Autenticação Qual a diferença? Autorização Baseada em Sessão: NÃO Autorização APIs devem ser sem estados (stateless) Autorização Implementação em Mobile pode ser custosa Autorização Baseada em Tokens: SIM Segurança Como proteger minha API? Segurança Evite expor IDs sequenciais (use HashIDs por exemplo) Segurança Limite requisições, de forma configurável (throttling) SegurançaNão utilize logins por senha (exceto em apps próprios) Segurança API somente em HTTPS Dicas e Recursos Onde ir a seguir? OAuth 2.0 Fluxos de Autorização JWT Tokens de Autenticação GraphQL Negociação de Conteúdo e Documentação! (substitui o REST) ● Build APIs You Won’t Hate ● HTTP API Design Guide ● Open API Initiative ● Petstore (Swagger UI) ● 2 Legged OAuth ● API Evangelist Leituras ● Slack APIs You Won’t Hate ● ngrok ● Apigee ● Postman ● Paw Dicas Empatia é a chave Obrigado! @ravanscafi https://joind.in/talk/913dd Estamos Contratando! Dev BackEnd, Dev FrontEnd rscafi@leroymerlin.com.br Agradecimentos Agradecimentos especiais a todos do SlidesCarnival que fizeram e disponibilizaram o template da apresentação gratuitamente. Ao PHPSP pelo convite e organização do evento <3
Compartilhar