Upgrade to Pro — share decks privately, control downloads, hide ads and more …

APIs Eficazes com PHP

Ravan Scafi
November 24, 2016

APIs Eficazes com PHP

Construir uma API pode parecer fácil. Algumas rotas que retornam conteúdo em JSON, uma forma de autenticação e está pronta. Será mesmo? Uma API eficaz preocupa-se com os desenvolvedores que irão consumi-la. Entenda conceitos como autenticação, autorização, documentação, padronização e negociação de conteúdo. Conheça boas práticas, dicas de segurança, livros, pacotes e recursos úteis.

Essa talk foi apresentada no PHPSP + Talks #1 - Google
https://www.meetup.com/pt-BR/php-sp/events/235641294/

Por favor, avalie a palestra e/ou os slides!
https://joind.in/event/phpsp-talks-1/apis-eficazes-com-php

# Pacotes Relevantes
- Swagger PHP
https://github.com/zircote/swagger-php

- League OAuth2 Server
https://github.com/thephpleague/oauth2-server

- League OAuth2 Client
https://github.com/thephpleague/oauth2-client

- JWT
https://github.com/lcobucci/jwt

- League Fractal
https://github.com/thephpleague/fractal

# Links da Apresentação
- Tweet sobre a API da UPS
https://twitter.com/danharper7/status/748550285761601536

- OAuth 2.0 Specification
https://oauth.net/2/

- JWT.io
https://jwt.io/

- GraphQL
http://graphql.org/

- Livro Build APIs You Won’t Hate do Phil Sturgeon
https://leanpub.com/build-apis-you-wont-hate

- HTTP API Design Guide
https://github.com/interagent/http-api-design

- Open API Initiative
https://openapis.org/

- Petstore (Swagger UI)
http://petstore.swagger.io/

- 2 Legged OAuth
http://stackoverflow.com/questions/14250383/how-does-2-legged-oauth-work-in-oauth-2-0

- API Evangelist
http://apievangelist.com/

- Slack APIs You Won’t Hate
https://slack.apisyouwonthate.com/

- ngrok
https://ngrok.com/

- Apigee
http://apigee.com/about/

- Postman
https://www.getpostman.com/

- Paw
https://paw.cloud/

Agradecimento ao Slides Carnival
http://www.slidescarnival.com/

Ravan Scafi

November 24, 2016
Tweet

More Decks by Ravan Scafi

Other Decks in Technology

Transcript

  1. APIs Eficazes
    Com PHP

    View Slide

  2. Sobre Mim
    Ravan Scafi
    Back-end Developer na Leroy Merlin Brasil
    Co-organizador do Meetup do Laravel SP
    @ravanscafi

    View Slide

  3. API?
    O que é uma API?

    View Slide

  4. 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.

    View Slide

  5. (ou porque a gente tá aqui hoje)
    API REST em 1 Minuto

    View Slide

  6. API REST em 1 minuto
    Cada recurso tem seu próprio URI
    GET http://meusite.dev/api/users/rscafi

    View Slide

  7. API REST em 1 minuto
    Verbos HTTP indicam a ação
    GET http://meusite.dev/api/users/rscafi

    View Slide

  8. API REST em 1 minuto
    Diferenciação por IDs
    GET http://meusite.dev/api/users/rscafi

    View Slide

  9. Motivação
    Por que fazer uma API?
    E o que isto implica?

    View Slide

  10. Documentação
    Como e por que documentar uma API?

    View Slide


  11. apiary.io
    “Uma API é apenas tão boa
    quanto sua documentação”

    View Slide

  12. View Slide

  13. Swagger /
    Open API Initiative
    Uma forma de documentar sua API

    View Slide

  14. Swagger /
    Open API Initiative
    Único arquivo swagger.json (ou .yml)

    View Slide

  15. Swagger /
    Open API Initiative
    Consumível por humanos e máquinas

    View Slide

  16. {
    "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": "[email protected]"
    },

    View Slide

  17. "paths": {
    "/pet": {
    "post": {
    "tags": [
    "pet"
    ],
    "summary": "Add a new pet to the store",
    "description": "",
    "operationId": "addPet",
    "consumes": [
    "application/json",
    "application/xml"

    View Slide

  18. "parameters": [
    {
    "in": "body",
    "name": "body",
    "description": "Pet object that needs to (...)",
    "required": true,
    "schema": {
    "$ref": "#/definitions/Pet"
    }
    }
    ],
    "responses": {
    "405": {
    "description": "Invalid input"

    View Slide

  19. View Slide

  20. Documentação
    Mantenha próxima ao código

    View Slide

  21. Documentação
    Revisite periodicamente

    View Slide

  22. Documentação
    Se possível, faça Documentation-First

    View Slide

  23. View Slide

  24. /**
    * @SWG\Info(title="My First API", version="0.1")
    */
    /**
    * @SWG\Get(
    * path="/api/resource.json",
    * @SWG\Response(response="200", description="An example
    resource")
    * )
    */

    View Slide

  25. Empatia
    é a chave

    View Slide

  26. 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.

    View Slide

  27. Design
    O que me atentar ao fazer uma API?

    View Slide

  28. Versionamento
    Somente exponha a “versão cheia”
    (v1, v2)

    View Slide

  29. Versionamento
    Evite ao máximo Breaking Changes

    View Slide

  30. 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

    View Slide

  31. Proteja-se com Mutators
    Representam Recursos da API

    View Slide

  32. Proteja-se com Mutators
    Criam uma barreira entre seus Models
    e sua API

    View Slide

  33. Auxiliam em Typecasting
    e Relacionamentos
    Proteja-se com Mutators

    View Slide

  34. 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),
    ];
    }
    }

    View Slide

  35. 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),
    ];
    }
    }

    View Slide

  36. 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),
    ];
    }
    }

    View Slide

  37. 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),
    ];
    }
    }

    View Slide

  38. 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),
    ];
    }
    }

    View Slide

  39. 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),
    ];
    }
    }

    View Slide

  40. Negociação de Conteúdo
    Como ter uma comunicação eficiente com os usuários?

    View Slide

  41. JSON, XML, CSV?
    Negociação de Conteúdo

    View Slide

  42. Trazer Relacionamentos e Recursos
    Embeddados?
    Negociação de Conteúdo

    View Slide

  43. Metadados:
    URI, página atual, contagem total
    Negociação de Conteúdo

    View Slide

  44. Use cabeçalhos HTTP quando relevante
    Negociação de Conteúdo

    View Slide

  45. Respostas
    Como passar as informações corretas aos usuários?

    View Slide

  46. Padronize códigos HTTP de resposta
    Respostas

    View Slide

  47. Padronize campos de datas, floats, moedas
    Respostas

    View Slide

  48. Padronize Metadados
    Respostas

    View Slide

  49. Não reinvente a roda
    Respostas

    View Slide

  50. {
    "data": {
    "name": "John Doe",
    "email": "[email protected]",
    "birthday": "17/09/2016"
    }
    }
    Faça um “wrap” da resposta
    {
    "name": "John Doe",
    "email": "[email protected]",
    "birthday": "17/09/2016"
    }

    View Slide

  51. {
    "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
    }

    View Slide

  52. {
    "errorCode": 500,
    "errors": [
    "Unknown error occurred.
    Check you input or try again
    later."
    ]
    }
    Nunca exponha Exceções para o Usuário
    {
    "exception":
    “NullPointerException”
    }

    View Slide

  53. Autorização e
    Autenticação
    Como identificar meus usuários e suas permissões?

    View Slide

  54. Autorização e
    Autenticação
    Qual a diferença?

    View Slide

  55. Autorização
    Baseada em Sessão: NÃO

    View Slide

  56. Autorização
    APIs devem ser sem estados
    (stateless)

    View Slide

  57. Autorização
    Implementação em Mobile
    pode ser custosa

    View Slide

  58. Autorização
    Baseada em Tokens: SIM

    View Slide

  59. Segurança
    Como proteger minha API?

    View Slide

  60. Segurança
    Evite expor IDs sequenciais
    (use HashIDs por exemplo)

    View Slide

  61. Segurança
    Limite requisições, de forma configurável
    (throttling)

    View Slide

  62. Segurança
    Não utilize logins por senha
    (exceto em apps próprios)

    View Slide

  63. Segurança
    API somente em HTTPS

    View Slide

  64. Dicas e Recursos
    Onde ir a seguir?

    View Slide

  65. OAuth 2.0
    Fluxos de Autorização

    View Slide

  66. JWT
    Tokens de Autenticação

    View Slide

  67. GraphQL
    Negociação de Conteúdo e Documentação!
    (substitui o REST)

    View Slide

  68. ● Build APIs You Won’t Hate
    ● HTTP API Design Guide
    ● Open API Initiative
    ● Petstore (Swagger UI)
    ● 2 Legged OAuth
    ● API Evangelist
    Leituras

    View Slide

  69. ● Slack APIs You Won’t Hate
    ● ngrok
    ● Apigee
    ● Postman
    ● Paw
    Dicas

    View Slide

  70. Empatia
    é a chave

    View Slide

  71. Obrigado!
    @ravanscafi
    https://joind.in/talk/913dd

    View Slide

  72. Estamos Contratando!
    Dev BackEnd, Dev FrontEnd
    [email protected]

    View Slide

  73. 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

    View Slide