Ferramentas do usuário

Ferramentas do site


info:apirest:ent_doc_restf_api:start

Diferenças

Aqui você vê as diferenças entre duas revisões dessa página.

Link para esta página de comparações

info:apirest:ent_doc_restf_api:start [2019/11/08 13:49] (atual)
Samuel criada
Linha 1: Linha 1:
 +====== Anotações - Udemy/​Entendendo e Documentando REST/ RESTFul APIs ======
  
 +  * Anotações/​estudo sobre:
 +    * APIs
 +    * REST e
 +    * RESTful
 +      * retiradas do curso [[https://​www.udemy.com/​restful-apis/​|Udemy - Entendendo e documentando REST / RESTful APIs]]
 +        * que é ministrado por [[https://​www.udemy.com/​user/​jackson-pires-de-oliveira-santos-junior/​|Jackson Pires]]
 +      * e, as vezes, cópia na íntegra do conteúdo textual existente no curso
 +
 +  * __Privilegie__ o **autor** fazendo o curso :!:
 +===== API =====
 +
 +
 +  * **A**pplication **P**rogramming **I**nterface
 +    * Interface de Programação de Aplicativos
 +
 +  * Conjunto de rotinas
 +  * Padrões de programação
 +    * Para acesso a um aplicativo de software
 +    * ou Plataforma baseado na WEB
 +      * //não somente WEB//
 +
 +
 +==== API Application ====
 +
 +  * Desenvolvimento de um **backend** ​
 +    * Que é __independente__ ​
 +      * do que o lado **client** esteja usando
 +    * E que pode ser compartilhado ​
 +      * para qualquer **client**
 +
 +
 +==== Resource ====
 +
 +  * **Recursos**
 +    * São **elementos de informação**
 +      * __manipulados__ por um **identificado __global__**
 +      * O identificador é sempre um **substantivo**
 +        * E deve estar no **plural**
 +
 +
 +  * Exemplo:
 +    * Recurso: **Usuário**
 +    * Recurso(id):​ //​api.cpac.embrapa.br/​**users**//​
 +
 +
 +==== URI ====
 +
 +  * **U**niform **R**esource **I**dentifier - [[http://​www.rfc-editor.org/​info/​rfc2396| RFC 2396]]
 +    * **//​Identificador Uniforme de Recurso//**
 +    * É uma cadeia de caracteres compacta usada para
 +      * Identificar
 +      * Denominar
 +        * um recurso na Internet
 +
 +  * Exemplo:
 +    * Recurso: **Usuários**
 +    * URI: //​**api.cpac.embrapa.br/​users**//​
 +
 +==== URL ====
 +
 +  * **U**niform **R**esource **L**ocator - [[http://​www.rfc-editor.org/​info/​rfc1738| RFC 1738]]
 +    * **//​Localizador Padrão de recursos//​**
 +    * É o endereço de um recurso disponível em uma rede
 +    * Têm-se o protocolo para comunicação
 +      * Na internet é o endereçamento completo
 +
 +  * Exemplo:
 +    * Recurso: **Impressora**
 +    * URL/URI: //​**https:<​nowiki>//</​nowiki>​api.cpac.embrapa.br/​print**//​
 +
 +==== URN ====
 +
 +  * **U**niform **R**esource **N**ame - [[https://​www.ietf.org/​rfc/​rfc2141.txt|RFC 2141]]
 +    * **//Nome Uniforme de Recurso//**
 +    * Para composição de suas [[info:​apirest:​start#​uri|URI]]
 +      * Utiliza-se de **URN Scheme** que estabelece
 +        * Identificação única do recurso
 +        * de forma persistente e
 +        * independente de localização
 +
 +  * Não é muito utilizado
 +    * e também não homologada
 +==== IRI ====
 +
 +  * **I**nternationalized **R**esource **I**dentifier
 +    * **//​Indentificador de Recurso Internacionalizado//​**
 +
 +  * Os [[info:​apirest:​start#​uri|URI]] são limitados a um subconjunto de caracteres
 +    * do conjunto de caracteres **ASCII**
 +
 +  * Os IRIs podem conter caracteres do [[https://​www.iso.org/​standard/​69119.html|Conjunto Universal de Carateres - ISO/IEC 10646 2017]]
 +
 +
 +  * É a possibilidade de utilização de caracteres não usuais nas [[info:​apirest:​start#​uri|URIs]]
 +    * Caracteres como os encontrados aqui: [[http://​www.columbia.edu/​kermit/​utf8-t1.html|Unicode 4.0 / ISO 10646 Plane 0]]
 +
 +===== REST =====
 +
 +  * **RE**presentational **S**tate **T**ransfer
 +    * **//​Transferência de Estado Representacional//​**
 +
 +  * Introduzido e definido no ano 2000
 +    * Tese de Ph.D de //Roy Fielding//
 +      * Um dos __principais autores__ ​ da especificação do Protocolo **HTTP**
 +    * Visava a **formalização** ​
 +    * De um conjunto de **melhores práticas**
 +      * Denominadas de **Constraints**
 +
 +  * **Constraints**
 +    * Possuem o objetivo de determinar a forma que os padrões
 +      * **HTTP**
 +      * [[info:​apirest:​start#​uri|URI]] ​
 +    * deveriam ser modelados
 +    * aproveitando de fato todos os recursos que ofereciam
 +
 +  * Assim, //Roy Fielding// ​
 +    * Estabeleceu,​ conforme a visão dele, algumas regras
 +    * que serão elencadas abaixo
 +
 +==== Cliente Servidor ====
 +
 +  * Principal Característica:​
 +    * **Separar as responsabilidades**
 +      * de diferentes partes de um sistema
 +
 +  * Uma, das diversas maneiras, de fazer esta divisão seriar separar
 +    * **Interface do usuário** (//​front-end//​)
 +    * do **Back-end** da aplicação (//​servidor//​)
 +
 +  * Isto possibilita,​ por exemplo,
 +    * Evoluir a **escalabilidade** das responsabilidades do servidor
 +    * de __forma independente__
 +      * O //​front-end//​ fica itocável
 +        * se não houver necessidade.
 +
 +==== Stateless ====
 +
 +  * Cada **requisição**
 +    * __não__ deve ter **ligação**
 +    * com requisições **//​anteriores//​** ou **//​futuras//​**
 +      * Ela é possuidora de **todas** as __informações necessárias__
 +      * para que seja tratada com sucesso pelo servidor
 +
 +  * O contrário, //​stateful//,​
 +    * que é armazenar informações ​
 +      * afim de que possa saber o que foi feito previamente
 +    * traz alguns malefícios ​
 +      * conforme surge a necessidade de escalar sua aplicação
 +
 +==== Cache ====
 +
 +  * Visa performance
 +    * sistemas **REST** deve permitir
 +    * que suas __respostas__ sejam passíveis de **cache**
 +
 +==== Interface Uniforme ====
 +
 +  * Para que o sistema possua uma **interface modelada**
 +    * pois é o meio utilizado pelo cliente
 +    * para poder **manipular** os conceitos estabelecidos
 +  * deve-se dedicar muito esforço
 +
 +  * E seguir padrões importantes ​
 +    * Considerando elementos como:
 +      * [[info:​apirest:​start#​resource|Recursos]]
 +      * **Mensagens autodescritivas**
 +      * **Hypermidia**
 +
 +==== Sistemas em Camadas ====
 +
 +  * Assim como a escalabilidade é necessária para sistemas distribuídos
 +
 +  * O sistema **REST** deve ter capacidade de adicionar ​
 +    * __elementos intermediários__
 +    * e que sejam __totalmente transparentes__ ​
 +  * para seus clientes
 +
 +  * Exemplo: //​Balanceador de Carga//
 +    * Requisições redirecionadas para os servidores menos sobrecarregados
 +
 +==== Código sob demanda ====
 +
 +  * Trazer flexibidade para o lado cliente
 +    * **Disponibilizar** recursos
 +      * uma biblioteca JS por exemplo
 +    * **apenas** __quando requisitada__ por determinada página
 +
 +  * É **opcional**
 +    * Por ser uma prática que
 +      * **reduz** a //​__visibilidade__//​
 +    * pois abre a possibilidade de uma falha na segurança
 +
 +===== REST vs RESTful =====
 +
 +  * **REST**
 +    * é o **modelo**
 +      * as __características__
 +    * **Conjunto** de __melhores práticas__ = **CONSTRAINTS**
 +
 +  * **RESTful**
 +    * a **implementação**
 +      * o quanto das características do modelo
 +      * estão sendo utilizadas
 +
 +  * A API que não segue os principios **REST**
 +    * é apenas uma __API HTTP__
 +
 +  * Se segue/​implementa os principios
 +    * é **RESTful**
 +
 +==== Representações ====
 +
 +  * São os **formatos** em que a informação __será devolvida__ (respondida)
 +    * quando requisitada pelo cliente.
 +    * As mais utilizadas:
 +
 +  * **JSON**
 +    * **J**ava**s**cript **O**bject **N**otation
 +    * **Estrutura** do tipo __chave-valor__
 +
 +<code javascript>​
 +{
 +    "​glossary":​ {
 +        "​title":​ "​example glossary",​
 +        "​GlossDiv":​ {
 +            "​title":​ "​S",​
 +            "​GlossList":​ {
 +                "​GlossEntry":​ {
 +                    "​ID":​ "​SGML",​
 +                    "​SortAs":​ "​SGML",​
 +                    "​GlossTerm":​ "​Standard Generalized Markup Language",​
 +                    "​Acronym":​ "​SGML",​
 +                    "​Abbrev":​ "ISO 8879:​1986",​
 +                    "​GlossDef":​ {
 +                        "​para":​ "A meta-markup language, used to create markup languages such as DocBook.",​
 +                        "​GlossSeeAlso":​ [
 +                            "​GML",​
 +                            "​XML"​
 +                        ]
 +                    },
 +                    "​GlossSee":​ "​markup"​
 +                }
 +            }
 +        }
 +    }
 +}
 +</​code>​
 +
 +  * **XML**
 +    * E**x**tensible **M**arkup **L**anguage
 +    * Linguagem de marcação (**tags**)
 +
 +<code xml>
 +<​!DOCTYPE glossary PUBLIC "​-//​OASIS//​DTD DocBook V3.1//​EN">​
 +<​glossary>​
 +    <​title>​
 +        example glossary
 +    </​title>​
 +    <​GlossDiv>​
 +        <​title>​
 +            S
 +        </​title>​
 +        <​GlossList>​
 +            <​GlossEntry ID="​SGML"​ SortAs="​SGML">​
 +                <​GlossTerm>​
 +                    Standard Generalized Markup Language
 +                </​GlossTerm>​
 +                <​Acronym>​
 +                    SGML
 +                </​Acronym>​
 +                <​Abbrev>​
 +                    ISO 8879:1986
 +                </​Abbrev>​
 +                <​GlossDef>​
 +                    <​para>​
 +                        A meta-markup language, used to create markup languages such as DocBook.
 +                    </​para>​
 +                    <​GlossSeeAlso OtherTerm="​GML">​
 +                    <​GlossSeeAlso OtherTerm="​XML">​
 +                </​GlossDef>​
 +                <​GlossSee OtherTerm="​markup">​
 +            </​GlossEntry>​
 +        </​GlossList>​
 +    </​GlossDiv>​
 +</​glossary>​
 +</​code>​
 +
 +  * Exemplos de representações tiradas:
 +    * [[https://​json.org/​example.html| JSON/XML Example]]
 +
 +===== SOAP =====
 +
 +  * Esta seção é proveniente do livro: [[https://​www.packtpub.com/​application-development/​building-restful-web-services-net-core|Building RESTful Web services with .NET Core]]
 +
 +  * **S**imple **O**bject **A**ccess **P**rotocol
 +    * Protocolo de troca de mensagens entre computadores baseado no XML
 +    * Os protocolos utilizados geralmente são o
 +      * **HTTP**(**H**yper**t**ext **T**ransfer **P**rotocol)
 +      * e **SMTP** (**S**imple **M**ail **T**ransfer **P**rotocol)
 +    * E são utilizados para mensagens de __negociação__ e **transmissão**
 +  * A [[https://​www.w3.org/​TR/​soap/​|proposta padrão]] é feita e mantida pela [[https://​www.w3.org/​|W3]]
 +
 +^  Estrutura SOAP  ^^
 +|  Envelope ​ | __Elemento obrigatório__ desta estrutura. Define o **ínicio** e o **fim** da mensagem |
 +|  Header ​ | **Opcional** e sempre deve vir __antes__ do elemento **Body**. Contém informações a respeito da messagem que pode ser usado para processá-la. |
 +|  Body  | **Principal** parte e elemento **obrigatório** e **único** nesta estrutura. Contém a __mensagem XML__ propriamente dita |
 +|  Fault  | Se houver **algum** tipo de **falha** no processamento da mensagem SOAP este **elemento** pode ser **adicionado** com __informações adicionais__ sobre o ocorrido. |
 +===== REST vs SOAP =====
 +
 +  * //O **REST** é um modelo arquitetural//​
 +    * //Já o **SOAP**, de fato, é um protocolo//
 +
 +^  REST  ^  SOAP  ^
 +|  Modelo arquitetural ​ |  Protocolo ​ |
 +|  Requisição HTTP simples ​ |  Usa **SOAP** envelopado no **HTTP** para fazer chamadas **RPC** (**R**emote **P**rocedure **C**all) ​ |
 +|  Suporta vários tipos de formato (XML, JSON, YAML)  |  Suporta somente XML  |
 +
 +===== cURL =====
 +
 +  * [[https://​curl.haxx.se/​ | cURL - command line tool and library for transferring data with URLs]]
 +
 +  * Ferramenta que permite
 +    * //envio// de requisições
 +    * //​recebimento//​ de respostas
 +      * dada uma [[info:​apirest:​start#​url|URL]].
 +      * Isto inclui, inclusive, envio de arquivos
 +
 +  * Possui extensa variedade de **opções**
 +    * usadas para __modificar__ as **requisições**,​ conforme a necessidade
 +    * e assim __saber__(//​esperar//​) qual **resposta** o servidor retornará
 +
 +
 +==== Instalação ====
 +
 +  * **Ubuntu**
 +    * // sudo apt install curl //
 +
 +  * **CentOS**
 +    * // sudo yum install curl //
 +
 +  * **MacOS**
 +    * // brew install curl //
 +
 +  * **Windows**
 +    * **32** bits ou **64** bits
 +      * https://​curl.haxx.se/​download.html
 +        * download de arquivo **ZIP** de acordo com sua arquitetura
 +    * Extraia o conteúdo em uma pasta qualquer
 +      * Coloque a sub-pasta **bin** no **PATH** do Windows
 +
 +  * [[https://​onlinecurl.com/​|Online]]
 +
 +==== Opções ====
 +
 +  * A sintaxe de utilização do **cURL**:
 +
 +   curl [opções...] <url>
 +
 +  * **Atentar** ao //​__case-sensitive__//​
 +    * **Dúvidas** nesta seção? ​
 +      * Consultar: [[https://​curl.haxx.se/​docs/​manpage.html|cURL.1 The Man page]]
 +
 +  * Para __testes__/​__prototipação__ usar:
 +    * [[https://​jsonplaceholder.typicode.com/​|JSONPlaceholder]]
 +      * É um serviço online REST que pode ser usado quando houver necessidade de dados não reais.
 +
 +  * **-H** ou **<​nowiki>​--</​nowiki>​header**
 +    * **H**eader (//​cabeçalho//​),​ permite
 +      * adicionar
 +      * substituir
 +        * cabeçalhos HTTP
 +      * //-H "​Content-Type:​ application/​json"//​
 +        *  um exemplo
 +
 +  * **-d** ou **<​nowiki>​--</​nowiki>​data**
 +    * **D**ata (//dados//)
 +    * Para **envio** de dados ao servidor
 +      * //-d '​{"​nome":​ "Nome do usuário"​}'//​
 +
 +
 +  * **-i** ou **<​nowiki>​--</​nowiki>​include**
 +    * Para visualizar o corpo da resposta do servidor
 +      * **adicionando** também o cabeçalho (//​Header//​)
 +
 +  * **-I** ou **<​nowiki>​--</​nowiki>​head**
 +    * Para visualizar **apenas** o cabeçalho(//​Header//​) da resposta
 +      * Exclui-se o corpo da mesma
 +
 +  * **-X** ou **<​nowiki>​--</​nowiki>​request**
 +    * Especifica qual o **__verbo__** HTTP a ser utilizado na requisição.
 +    * Padrão: **GET**
 +      * Opções de verbos:
 +        * **POST**
 +        * **PUT**
 +        * **PATCH**
 +        * **DELETE**
 +      * Mais detalhes na seção [[info:​apirest:​start#​metodos_verbos_http|Métodos/​Verbos HTTP]]
 +
 +==== Alternativas ====
 +
 +  * [[https://​httpie.org/​|HTTPie]]
 +    * Sintaxe de comando facilitada
 +    * Saída formatada e colorida
 +    * Suporte as principais plataformas
 +
 +  * [[https://​www.getpostman.com/​|Postman]]
 +    * Possui aplicativo específico para o //Google Chrome//
 +    * Interface visual rica e facilitada
 +===== Analisando uma resposta HTTP =====
 +
 +  * Para toda requisição HTTP
 +    * //​decorrendo normalmente o fluxo//
 +    * haverá uma resposta HTTP
 +
 +  * Para o comando abaixo:
 +
 +    curl -i https://​jsonplaceholder.typicode.com/​posts/​1
 +
 +  * a resposta da requisição acima, o cURL a divide em 4 partes:
 +
 +  * **Start-line** (//linha de ínicio//)
 +    * __Obrigatória__,​ consiste em:
 +      * **Request-line**
 +      * **Status-line**
 +
 +  * **Header fields** (//​cabeçalho de campos//)
 +     * Pode ter **nenhum** ou **vários**
 +     * São os **metadados** da requisição e da resposta HTTP
 +     * Indicam como a transferência de dados deve ser manipulada
 +       * Também utiliza-se de uma estrutura __chave-valor__
 +     * Cabeçalhos comuns:
 +       * **Content-Type**
 +         * Indica como a representação é serializada
 +       * **Content-Length**
 +         * Indica o tamanho do corpo da mensagem ​
 +         * É indicado em **octetos**
 +       * **X-Powered-By**
 +         * Cabeçalhos iniciados com **X** (//​geralmente//​) são __não oficiais__.
 +         * Cabeçalhos __não oficiais__ **são** uma prática em **__desuso__**
 +           * Devendo-se usar os **cabeçalhos oficiais** e em **__último__** caso criar novo cabeçalho.
 +           * Para leitura:
 +             * [[https://​developer.mozilla.org/​en-US/​docs/​Web/​HTTP/​Headers|Headers(cabeçalhos)]]
 +             * Existe uma discussão que recomenda-se não utilizar **X** no inicio de cabeçalhos __não oficiais__
 +               * [[http://​stackoverflow.com/​questions/​3561381/​custom-http-headers-naming-conventions|Custom HTTP Headers naming conventions]]
 +
 +  * **Empty line** (//linha em branco//)
 +     * __Obrigatória__
 +     * É o delimitador(//​separador//​) entre os cabeçalhos e o corpo da mensagem
 +
 +  * **Message-body** (//corpo da mensagem//)
 +     * Opcional
 +     * São os dados **//​devolvidos//​** pelo servidor
 +       * a partir de uma requisição feita
 +     * Estes dados vem representados numa formato específico
 +       * Informado pelo cabeçalho **Content-Type**
 +
 +  * As respostas podem variar, mas a __linha inicial__ e a __linha em branco__ **existirão**.
 +
 +<​code>​
 +HTTP/1.1 200 OK
 +Date: Tue, 29 May 2018 18:59:19 GMT
 +Content-Type:​ application/​json;​ charset=utf-8
 +Content-Length:​ 292
 +Connection: keep-alive
 +Set-Cookie: __cfduid=d2d95ef16ebfb3debecf22ca221f945911527620359;​ expires=Wed,​ 29-May-19 18:59:19 GMT; path=/; domain=.typicode.com;​ HttpOnly
 +X-Powered-By:​ Express
 +Vary: Origin, Accept-Encoding
 +Access-Control-Allow-Credentials:​ true
 +Cache-Control:​ public, max-age=14400
 +Pragma: no-cache
 +Expires: Tue, 29 May 2018 22:59:19 GMT
 +X-Content-Type-Options:​ nosniff
 +Etag: W/"​124-yiKdLzqO5gfBrJFrcdJ8Yq0LGnU"​
 +Via: 1.1 vegur
 +CF-Cache-Status:​ HIT
 +Expect-CT: max-age=604800,​ report-uri="​https://​report-uri.cloudflare.com/​cdn-cgi/​beacon/​expect-ct"​
 +Server: cloudflare
 +CF-RAY: 422b328d6b484a4e-GRU
 +
 +{
 +  "​userId":​ 1,
 +  "​id":​ 1,
 +  "​title":​ "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",​
 +  "​body":​ "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"​
 +}
 +</​code>​
 +
 +  * Assim a resposta acima fica:
 +
 +^  Divisão ​ ^  Sub-divisão ​ ^  Conteúdo da resposta ​ ^
 +|  **Start-line**(//​Linha inicial//​) ​ | | HTTP/1.1 200 OK  |
 +| |  **//​Request-line//​** ​ |  //​HTTP/​1.1// ​ |
 +| |  **//​Status-line//​** ​ |  //200 OK//  |
 +|  **Headers**(//​cabeçalhos//​) ​ | | **Date**: Tue, 29 May 2018 18:59:19 GMT |
 +| | | **Content-Type**:​ application/​json;​ charset=utf-8 |
 +| | | **Content-Length**:​ 292 |
 +| | | **Connection**:​ keep-alive |
 +| | | **Set-Cookie**:​ <​nowiki>​__</​nowiki>​cfduid=d2d95ef16ebfb3debecf22ca221f945911527620359;​ expires=Wed,​ 29-May-19 18:59:19 GMT; path=/; domain=.typicode.com;​ HttpOnly |
 +| | | **X-Powered-By**:​ Express |
 +| | | **Vary**: Origin, Accept-Encoding |
 +| | | **Access-Control-Allow-Credentials**:​ true |
 +| | | **Cache-Control**:​ public, max-age=14400 |
 +| | | **Pragma**: no-cache |
 +| | | **Expires**:​ Tue, 29 May 2018 22:59:19 GMT |
 +| | | **X-Content-Type-Options**:​ nosniff |
 +| | | **Etag**: W/"​124-yiKdLzqO5gfBrJFrcdJ8Yq0LGnU"​ |
 +| | | **Via**: 1.1 vegur |
 +| | | **CF-Cache-Status**:​ HIT |
 +| | | **Expect-CT**:​ max-age=604800,​ report-uri="​https://​report-uri.cloudflare.com/​cdn-cgi/​beacon/​expect-ct"​ |
 +| | | **Server**: cloudflare |
 +| | | **CF-RAY**: 422b328d6b484a4e-GRU |
 +| **Empty-line**(//​linha em branco//) | | |
 +|  **Message-body** (//corpo da mensagem//​) ​ | | { |
 +| | | "​userId":​ 1, |
 +| | | "​id":​ 1, |
 +| | | "​title":​ "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",​ |
 +| | | "​body":​ "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" ​ |
 +| | | } |
 +
 +
 +===== Métodos/​Verbos HTTP =====
 +
 +  * Métodos ou Verbos
 +
 +  * São o total de **9** verbos ​
 +    * Para criação de uma //__API RESTful__//
 +      * Ou seja, seguindo as [[info:​apirest:​start#​rest|Constraints]] ​
 +    * E são a semântica __possível__
 +      * a serem aplicadas em um __determinado__ [[info:​apirest:​start#​resource|Recurso]]
 +
 +  * Na especificação original do HTTP apenas tinha-se estes três métodos:
 +    * **GET**
 +    * **POST**
 +    * **HEAD**
 +
 +  * Na revisão 1.1 adicionaram-se mais 5:
 +    * **OPTIONS**
 +    * **PUTS**
 +    * **DELETE**
 +    * **TRACE**
 +    * **CONNECT**
 +
 +  * A [[https://​tools.ietf.org/​html/​rfc5789|RFC 5789]] adicionou o método **PATCH**
 +
 +^  Verbos ​ ^  Operações ​ ^
 +|  **POST** ​ | **C**reate (//​incluir//​) ​ |
 +|  **GET** ​ | **R**ead (//​ler//​) ​ |
 +|  **PUT** ​ | **U**pdate (//​atualizar//​) ​ |
 +|  **DELETE** ​ | **D**elete (//​deletar//​) ​ |
 +==== GET ====
 +
 +  * Utilizado quando há __necessidade__ para se __obter__ um **recurso**
 +    * É um método **idempotente**
 +      * Independente da quantidade de vezes que é executado
 +      * o __resultado__ sempre será o **mesmo**
 +
 +  * **GET** já é __inferido__ no comando cURL mais simples
 +    * Exemplo, com adição do cabeçalho
 +
 +    curl -i https://​jsonplaceholder.typicode.com/​posts/​1
 +
 +  * Pode-se acrescentar a opção '​**-v**'​
 +    * para ficar ainda mais verborrágica a resposta
 +
 +
 +==== POST ====
 +
 +  * É usado para criar um [[info:​apirest:​start#​resource|recurso]]
 +    * por meio do uso de uma [[info:​apirest:​start#​representacoes|representação]]
 +
 +    curl https://​jsonplaceholder.typicode.com/​posts/​ \
 +        -X POST \
 +        -H "​Content-Type:​ application/​json"​ \
 +        -d '​{"​userId":​ 1, "​title":​ "Meu artigo",​ "​body":​ "Corpo do artigo......"​}'​
 +
 +  * O "​**\**"​ é apenas para a quebra do comando cURL em mais de uma linha
 +
 +  * Este comando quando executado
 +    * retornará apenas o corpo da mensagem (representação)
 +    * contendo mais um novo campo que é o **id** (simbolizando que foi feito '//​gravação//'​)
 +    * Contudo, caso faça um cURL padrão (**GET**)
 +      * talvez não seja encontrado o registro recém postado
 +      * porque o [[https://​jsonplaceholder.typicode.com/​|JSONPlaceholder]] apaga-o por padrão apenas mantendo os seus próprios registros
 +
 +==== PUT ====
 +
 +  * Visa a **atualização** de um recurso
 +    * //put// = //​colocar//,//​substituir//​
 +
 +
 +    curl https://​jsonplaceholder.typicode.com/​posts/​101 \
 +        -X PUT \
 +        -H "​Content-Type:​ application/​json"​ \
 +        -d '​{"​userId":​ 1, "​title":​ "Meu novo artigo",​ "​body":​ "Corpo do novo artigo......"​}'​
 +
 +==== DELETE ====
 +
 +  * Visa a **remoção** de um recurso
 +
 +    curl -X DELETE https://​jsonplaceholder.typicode.com/​posts/​101
 +
 +
 +==== HEAD ====
 +
 +
 +  * Similar ao método [[info:​apirest:​start#​get|GET]]
 +    * Ao receber uma requisição que usa este método
 +      * O servidor não retornará o //​message-body//​ em sua requisição.
 +      * Apenas o cabeçalho
 +        * Equivale a opção __**-I** / **<​nowiki>​--</​nowiki>​head**__ do comando **cURL**
 +
 +==== PATCH ====
 +
 +  * **Modifica** __parcialmente__ um recurso
 +    * //altera valores específicos//​
 +  * **Ao invés** de __enviar todos__ os dados **novamente**
 +    * Opondo-se ao [[info:​apirest:​start#​put|PUT]] que visa a substituição de um recurso existente.
 +
 +  * A vantagem está na redução do tráfico entre o servidor e cliente
 +
 +    curl -v https://​jsonplaceholder.typicode.com/​posts/​3 \
 +        -X PATCH \
 +        -H "​Content-Type:​ application/​json"​ \
 +        -d '​{"​title":"​Meu novo título"​}'​
 +
 +==== OPTIONS ====
 +
 +  * A requisição com este verbo retorna ao cliente
 +    * os **requisitos** de um determinado recurso
 +
 +  * Pode informar ​
 +    * quais são os __métodos__ (//​verbos//​)
 +      * podem ser aplicados a um determinado recurso
 +    * qual a URL permitida
 +      * para se comunicar com determinado recurso
 +
 +  * O cabeçalho [[https://​developer.mozilla.org/​en-US/​docs/​Web/​HTTP/​CORS#​Access-Control-Allow-Methods|CORS - Access Controlo Allow Methods]]
 +    * é utilizado para indicar quais são os métodos ​
 +    * utilizados por um determinado recurso
 +
 +
 +    curl -I -X OPTIONS https://​jsonplaceholder.typicode.com/​posts/ ​
 +
 +  * O comando acima **apenas** retorna o cabeçalho ​
 +  * e os métodos permitidos para a referida URL
 +
 +  * É possível, na __própria aplicação__,​ ao identificar uma requisição **OPTIONS**
 +    * incrementar a resposta do servidor informando no //​message-body//​
 +    * um **__descrição dos campos__**, como sugerido aqui:
 +      * [[http://​zacstewart.com/​2012/​04/​14/​http-options-method.html#​the-response-body-and-api-documentation|The response body and api documentation]]
 +
 +==== TRACE ====
 +
 +  * //Ecoa a requisição recebida//
 +    * //para o cliente saber se houveram mudanças//
 +    * //e adições feitas por servidores intermediários//​
 +
 +  * Semelhante ao comando [[https://​www.computerhope.com/​unix/​utracero.htm|traceroute]]
 +
 +  * Pode apresentar [[http://​www.cgisecurity.com/​questions/​httptrace.shtml|vunerabilidades]]
 +    * e por isso costuma ser __desabilitado__
 +      * retornando o [[https://​developer.mozilla.org/​en-US/​docs/​Web/​HTTP/​Status/​405|Erro 405 - Método não permitido]]
 +
 +    curl -i -X TRACE https://​jsonplaceholder.typicode.com/​posts/ ​
 +
 +==== CONNECT ====
 +
 +  * //Converte a requisição de conexão para um túnel TCP/IP transparente,//​
 +  * //​usualmente para facilitar comunicação criptografada com SSL(HTTPS)//​
 +  * //através de um proxy HTTP não criptografado.//​
 +
 +  * É uma configuração também feita no servidor
 +    * afim de fechar um túnel entre o cliente e o servidor
 +    * e tornar a comunicação criptografada
 +
 +===== Safe Methods =====
 +
 +  * São **safe methods**(//​métodos salvos//))
 +    * aqueles que que fazem nenhum efeito ​
 +    * de qualquer um dos lados (cliente/​servidor)
 +
 +  * Pode haver até uma implementação
 +    * como um contador de visitantes
 +      * mas o cliente não pode ser responsável pela alteração
 +        * não pode haver parâmetro vindo do cliente
 +        * que cause esta modificação
 +
 +
 +  * Os verbos que são **safe methods**
 +    * [[info:​apirest:​start#​get|GET]]
 +    * [[info:​apirest:​start#​head|HEAD]]
 +
 +===== Métodos idempotentes =====
 +
 +  * **Idempotente**:​
 +    * Propriedade de algumas operações matemáticas
 +      * e também encontrada na Ciência da Computação
 +    * que o resultado destas operações sempre são o mesmo
 +      * independente de quantas vezes forem executadas
 +
 +  * Em REST observa-se esta característica quando, por exemplo,
 +    * o envio de 10 requisições HTTP para um método idempotente
 +    * é o mesmo que o envio de uma única requisição
 +
 +  * Os métodos que tem essa característica:​
 +    * [[info:​apirest:​start#​get|GET]]
 +    * [[info:​apirest:​start#​head|HEAD]]
 +    * [[info:​apirest:​start#​put|PUT]]
 +    * [[info:​apirest:​start#​delete|DELETE]]
 +    * [[info:​apirest:​start#​options|OPTIONS]]
 +    * [[info:​apirest:​start#​trace|TRACE]]
 +
 +===== Modelo de maturidade Richardson =====
 +
 +  * //Roy Fielding// estabelece que uma API só RESTful ​
 +    * se seguir as características([[info:​apirest:​start#​rest|Constraints]]) definidas em seu trabalho.
 +
 +  * Isso traz em alguns cenários alguma dificuldade.
 +    * Assim, //Leonard Richardson//​ propôs um modelo de 4 níveis
 +      * afim de alcançar uma API REST
 +
 +  * Os níveis: ​
 +    * **0**
 +    * **1**
 +    * **2**
 +      * São familiares e fáceis de implementar
 +      * Contudo, não sã considerados RESTful
 +
 +==== Nível 0: POX ====
 +
 +  * **P**lain **O**ld **X**ml
 +    * Muitas APIs ditas como RESTFul se encontram neste nível de maturidade
 +    * As mensagens **podem** estar __serializadas__ em formatos como XML, JSON (e outros)
 +      * lembrando que e não é a [[info:​apirest:​start#​representacoes|representação]]
 +      * que **define** se é ou não um sistema REST
 +
 +    POST /savePost
 +    ​
 +    <​Post>​
 +       <​title>​Meu post numero 01</​title>​
 +       ...
 +    </​Post>​
 +
 +  * A tabela abaixo é outro exemplo deste nível:
 +
 +^  RPC(POX) ​ ^^^
 +^  Verbo HTTP  ^  URI  ^  Ação ​ ^
 +|  GET  |  /​getPosts/​1 ​ |  Visualizar ​ |
 +|  POST  |  /​savePosts ​ |  Criar  |
 +|  POST  |  /​updatePosts/​1 ​ |  Alterar ​ |
 +|  GET/​POST ​ |  /​delPosts/​1 ​ |  Remover ​ |
 +
 +  * No exemplo mais acima, a resposta está serializada
 +  * E a tabela mostra como está estrutura as chamadas
 +  * Os problemas encontrados são
 +    * __Não há uso__ da **constraint** de **nomeação** de **recurso**
 +    * E os verbos(//​métodos//​) não estão sendo devidamente utilizados
 +
 +  * Em nada difere do estilo de sistema **RPC** (**R**emote **P**rocedure **C**all)
 +      * apenas se tem **simples XML**s (**POX**) em envio e de resposta
 +
 +  * Encontra-se também neste nível
 +    * O uso indevido (ou errado mesmo) dos **códigos HTTP** na resposta
 +
 +  * Exatamente por estes 
 +    * códigos ​
 +    * e mensagens de erro 
 +  * serem trabalhados na aplicação,​ impede que elementos como
 +      * //Gateway//
 +      * //Proxies//
 +    * trabalhem de forma adequada
 +
 +    GET /getPosts/1
 +    HTTP/1.1 200 OK
 +    <​getPost>​
 +        <​status>​POST NÃO ENCONTRADO</​status>​
 +        <​code>​404</​code>​
 +    </​getPost>​
 +
 +  * O exemplo acima demonstra:
 +    * Código de retorno indevidamente no //​[[info:​apirest:​start#​analisando_uma_resposta_http|message-body]]//​
 +      * quando devia estar na //​[[info:​apirest:​start#​analisando_uma_resposta_http|start-line]]//​
 +      * no lugar do //**200 OK**//
 +
 +  * Se estivesse seguindo as constraints REST
 +    * Possibilitaria que **roteadores** e **proxies**
 +      * sabendo o devido status da resposta
 +    * **Priorizá-la** no tráfego.
 +
 +  * Esta **diferença** entre a __semântica HTTP__
 +  * E a __representação__ **gerada** pela //​aplicação//​
 +    * é o outro maior problema encontrado neste nível
 +==== Nível 1: Recursos ====
 +
 +  * Já têm-se uma API modelada com os [[info:​apirest:​start#​resource|Recursos]]
 +    * não precisa-se saber a funcionalidade das URI
 +    * apenas saber quais recursos têm-se acesso
 +
 +  POST /posts
 +  ​
 +  <​Post>​
 +      <​title>​Meu post numero 02</​title>​
 +      ...
 +  </​Post>​
 +  ​
 +
 +^  REST  ^^^
 +^  Verbo HTTP  ^  URI  ^  Ação ​ ^
 +|  GET  |  /​posts/​1 ​ |  Visualizar ​ |
 +|  POST  |  /​posts ​ |  Criar  |
 +|  PUT  |  /​posts/​1 ​ |  Alterar ​ |
 +|  DELETE ​ |  /​posts/​1 ​ |  Remover ​ |
 +
 +==== Nível 2: Verbos HTTP ====
 +
 +  * HTTP não serve mais apenas para transporte
 +    * Passa a exercer papel semântico na API
 +    * Os verbos possuem propósito para qual foram criados
 +
 +  * O uso dos métodos mais conhecidos
 +    * o uso corretos do códigos de resposta
 +      * permitem a modelagem e interação com os recursos da API
 +
 +  * //Envio//:
 +
 +    POST /posts
 +    ​
 +    <​Post>​
 +        <​title>​Meu post numero 02</​title>​
 +        ...
 +    </​Post> ​
 +
 +  * //​Recebimento//: ​
 +    * //Tendo ainda a informação,​ neste exemplo//:
 +      * // que o recurso foi criado com sucesso = **código** da resposta//
 +      * // local do recurso recém criado = **Header** __location__//​
 +
 +    201 Created ​
 +    Location: /​posts/​101 ​
 +
 +=== Código de Status HTTP ===
 +
 +  * [[https://​developer.mozilla.org/​en-US/​docs/​Web/​HTTP/​Status|Status - Referência]]
 +    * Conhecê-los é importante, pois permite maior transparência a sua API
 +==== Nível 3: HATEOAS ====
 +
 +  * **H**ypermedia **A**s **T**he **E**ngine **O**f **A**pplication **S**tate
 +    * //​Hipermídia como motor do estado da aplicação//​ (em uma tradução rústica)
 +      * __//​Controle de Hipermídia//​__
 +
 +  * Para //Roy Fielding// essa característica é obrigatória
 +    * Se não houver, a aplicação __não é__ RESTful
 +
 +  * O //HATEOAS// tem como elemento principal
 +    * Uma representação **hipermídia** (//é a capacidade de um documento se ligar a outro//)
 +      * O documento tem como descrever ​
 +        * seu estado atual
 +        * E quais são seus relacionamentos ​
 +          * com outros futuros estados
 +
 +  * Resgata-se neste momento a **constraint** [[info:​apirest:​start#​stateless|Stateless]]
 +
 +  * Para aplicação desta constraint, utiliza-se o **HATEOAS**
 +      * A resposta do servidor precisa constar
 +        * qual estado do referido recurso
 +        * e seu possível(is) relacionamento(s) com outro(s) futuro(s) estado(s)
 +
 +    GET /posts/101
 +
 +    HTTP/1.1 200 OK
 +    ​
 +    <​Posts>​
 +        <​Id>​101</​Id>​
 +        <​Title>​Manoel da Silva</​Title>​
 +        <link rel="​delete"​ href="/​posts/​101"​ />
 +        <link rel="​notify"​ href="/​posts/​101/​notify"​ />
 +    </​Posts>​
 +
 +
 +  * No exemplo acima, é feito uma requisição,​ na primeira linha
 +
 +  * A resposta trouxe o código de status (//​status-code//​) como **OK**
 +    * e no corpo da mensagem (//​message-body//​):​
 +      * É retornado devidamente o recurso
 +        * **Id**
 +        * **Title**
 +    * E abaixo vem os __estados vinculados__ ao referido recurso
 +      * //Deletar//
 +      * //​Notificar//​
 +
 +  * São estes os exemplos de controles que o referido documento(//​recurso//​)
 +    * Oferece (//​descreve//​) sobre si mesmo.
 +
 +===== Tipo de mídia =====
 +
 +  * Ou //Media type// ​
 +    * é uma string que define o formato de dado
 +    * e como a máquina deve ler tal formato
 +      * //"... representação específica de uma resposta a uma requisição"//​
 +    * Que é o novo nome para [[https://​developer.mozilla.org/​en-US/​docs/​Glossary/​MIME_type
 +| MIME Type]]
 +
 +  * Exemplos:
 +    * //​application/​json//​
 +    * //​application/​xml//​
 +    * //​multipart/​form-data//​
 +    * //​text/​html//​
 +
 +  * Sua estrutura segue o padrão: <<​tipo>>​**/​**<<​sub-tipo>​
 +    * Pode-se incluir alguns parâmetros adicionais como **//​charset//​**
 +
 +  * Alguns **tipos**:
 +    * //​application//​
 +    * //audio//
 +    * //example//
 +    * //image//
 +    * //model//
 +    * //message//
 +    * //​multipart//​
 +    * //text//
 +    * //video//
 +      * [[https://​www.iana.org/​assignments/​media-types/​media-types.xhtml|Iana.org - Media Types]]
 +
 +  * O **header** (//​cabeçalho//​) utilizado para informar o //media type// é
 +    * **Accept** ​
 +      * No ato da requisição indica-se como a __resposta será aceita__ ao indicar o formato
 +
 +    curl mockbin.org/​request -H "​Accept:​ application/​json"​
 +    ​
 +    curl mockbin.org/​request -H "​Accept:​ application/​xml"​
 +    ​
 +    curl mockbin.org/​request -H "​Accept:​ application/​yaml"​
 +
 +  * **Reforça-se** assim que é o __cabeçalho__ que importa e **não** a URL 
 +    * __quanto a definição__ do formato trafegado
 +
 +  * [[http://​mockbin.org/​]]
 +    * Usa-se para testes
 +      * Semelhante ao [[ https://​jsonplaceholder.typicode.com|JSONPlaceHolder]]
 +
 +  * O header **Accept** permite incluir parâmetros para o referido formato
 +    * Assim como também incluir mais de um formato
 +      * Separandos por vírgula '​**,​**'​
 +
 +    curl mockbin.org/​request -H "​Accept:​ application/​json;​q=0.5,​ application/​yaml;​q=0.1"​
 +
 +  * O parâmetro **q** significa **Quality Factor**
 +    * Valores esperados: **0** à **1** 
 +      * da //menor// para //maior// __prioridade__
 +    * Define a ordem preferida de retorno
 +
 +  * Para finalizar: //​Content-Type//​ vs //Accept//
 +    * **Content-Type**:​ formato dos dados no **envio** (//​requisição//​) ​
 +    * **Accept**: formato dos dados **recebimento**(//​resposta//​)
 +
 +===== Gestão de erros =====
 +
 +  * O retorno de uma requisição RESTful pode trazer um erro, causado por:
 +    * Falha no **formato** da requisição
 +    * Causas **internas** referentes ao servidor
 +
 +  * Objetiva-se assim:
 +    * Informar o requisitante uma __mensagem que retrate__ o que de fato ocorreu
 +    * Juntamente com um **status-code** __não genérico e útil__
 +      * Nem sempre o **message-body** pode vir com o log de rastreio do erro
 +
 +==== Classes HTTP Status Code ====
 +
 +  * [[https://​developer.mozilla.org/​pt-BR/​docs/​Web/​HTTP/​Status| Mozilla HTTP response status codes]]
 +    * Ou [[https://​httpstatuses.com/​|HTTP Status Codes Portal]]
 +
 +=== 1xx - Informacional ===
 +
 +  * Não muito utilizado nos dias de hoje
 +
 +=== 2xx - Sucesso ===
 +
 +  * **204** - //NO CONTENT//
 +    * __Resposta ideal__ para quando o servidor cumpriu a requisição com sucesso.
 +      * Como por exemplo, quando é feita uma requisição com o método **DELETE**
 +      * para remover um referido **recurso** e este é removido __devidamente__.
 +
 +=== 3xx - Redirecionamento ===
 +
 +=== 4xx - Erro Cliente ===
 +
 +  * **400** - //BAD REQUEST// (//​Requisição mal-formulada//​ - adaptando...)
 +    * __Resposta ideal__ para uma requisição que, por exemplo, utilizando-se do **POST**
 +    * envia dados cuja //​representação//​ é **JSON**, mas este, não foi bem formatado.
 +      * Deve-se então detalhar o erro no //​message-body//​
 +    * Este é um código status de __erro genérico__
 +      * Por isso a necessidade de especificar o erro no corpo da mensagem.
 +      * Para //tentar esclarecer//​ qual é a __má formulação na sintaxe__ da requisição
 +
 +  * **404** - //NOT FOUND// (//Não encontrado//​)
 +    * __Resposta ideal__ para qualquer **recurso** não encontrado.
 +      * E sempre especificando no //​message-body//​ com informações que houver
 +
 +  * **405** - //METHOD NOT ALLOWED// (//Método não permitido//​)
 +    * __Resposta ideal__ para uma requisição cujo __método solicitado__
 +      * //**Não está** disponível/​permitido//​
 +
 +  * **406** - //NOT ACCEPTABLE//​ (//Não aceito//)
 +    * __Resposta ideal__ para uma requisição que em seu __cabeçalho__
 +      * __solicita__ uma __representação__,​ a qual __**não é** permitida/​disponível__
 +
 +  * **409** - //​CONFLICT//​ (//​Conflito//​)
 +    * __Resposta ideal__ para indicar ao cliente que houve um conflito e será necessário
 +    * reformular a requisição.
 +    * Um exemplo comum para seu uso é a __inclusão de um recurso já existente__
 +      * Novamente, devolve-se este código de status
 +      * e no //​message-body//​ informa-se a causa em maior detalhes do erro identificado
 +
 +  * **410** - //GONE// (//Já foi// - grosseiramente traduzido...)
 +    * __Resposta ideal__ para indicar que o recurso realmente existiu
 +      * mas não encontra-se mais disponível
 +      * Cenário ideal de uso deste código de status é logo após
 +        * uma requisição de método **DELETE**
 +        * cujo retorno foi **204** //No Content//
 +
 +
 +  * **415** - //​UNSUPPORTED MEDIA TYPE// (//Tipo mídia não suportada//​)
 +    * __Resposta ideal__ para uma requisição que utiliza, por exemplo, o método **POST**
 +    * e define em seu //​cabeçalho//​ que os dados enviados são
 +    * de um **Content-Type** não suportado pelo servidor
 +
 +=== 5xx - Erro Servidor ===
 +
 +
 +===== Versionamento =====
 +
 +  * Com adventos como:
 +    * crescimento da própria API
 +    * novos recursos para 
 +      * novas funcionalidades
 +      * ou funcionalidades existentes
 +    * modificações nas funcionalidades existentes
 +
 +  * Pode-se para estes casos fazer o **versionamento** da API
 +
 +  * O //​Versionamento//​ visa também ​
 +    * que o cliente possa manter o seu uso atual da API
 +      * até que também tenha condições de migrar para as novas versões
 +
 +  * Não faz parte das [[info:​apirest:​start#​rest|constraints REST]]
 +    * e nem do [[info:​apirest:​start#​modelo_de_maturidade_richardson|Modelo de Maturidade de Richardson]]
 +
 +==== Tipos de Versionamento ====
 +
 +  * **Subdomínio**
 +    * **api01**.meudominio.com/​usuarios
 +
 +  * **URL**
 +    * meudominio.com/​**v01**/​usuarios
 +    * usando __**parâmetros**__
 +      * meudominio.com/​usuarios?​apiv=01
 +
 +  * **HTTP Header Customizado**
 +    * //​X-API-Version:​ 1//
 +      * __Header não oficial__, definido pelo desenvolvedor
 +
 +  * **Accept** Header + **Media Type** (//​Cabeçalho Accept + Tipo de mídia//)
 +    * //Accept: application/​vnd.myapi.v2+json//​
 +
 +  * **Accept** Header com **opção de versão**
 +    * //Accept: application/​vnd.myapi+json;​version=2.1//​
 +
 +  * A opção **URL** __costuma-se ser a mais escolhida__
 +    * Por ter fácil implementação
 +    * Minimiza erros de desenvolvedores inexperientes
 +    * Fácil compartilhamento de URLs
 +
 +  * Exemplos de APIs versionadas
 +    * [[https://​dev.pagseguro.uol.com.br/​documentacao/​pagamentos/​pagamento-padrao|PagSeguro]]
 +    * [[https://​developer.paypal.com/​docs/​api/​|Paypal]]
 +
 +===== Caching =====
 +
 +  * //"​...é um importante processo da ciência da computação//​
 +    * //que está presente em qualquer computador das mais diversas formas.//
 +    * //Há//
 +      * //memórias caches//
 +      * //discos de cache para hardware e software//
 +      * //cache de páginas etc.//
 +    * //Até mesmo a memória virtual é uma forma de __caching__"//​
 +        * __//​**trecho extraído e traduzido de** [[https://​computer.howstuffworks.com/​cache.htm|How Caching Works]]//__
 +
 +  * Mais informações em [[https://​developer.mozilla.org/​en-US/​docs/​Web/​HTTP/​Caching|Mozilla - Caching]]
 +
 +  * O //caching// busca reduzir o custo de rodar as requisições das aplicações.
 +    * Em REST, o ganho é dos dois lados:
 +      * __Cliente__:​ pelo rápido retorno de sua solicitação
 +      * __Servidor__:​ uma carga a menos para processamento
 +
 +  * Deve-se buscar o //caching//
 +    * apenas para __as coisas que não mudam com muita frequência__
 +
 +  * Características:​
 +    * __Redução__ de tempo na busca da informação
 +      * Menor __custo__ no **processamento** utilizado pelas aplicações no servidores
 +    * A aplicação que implementa cache corretamente é __mais escalável__
 +      * Principalmente se a maioria das requisições retornam dados
 +    * Com exceção de dados de tempo-real
 +      * Os __demais dados serão cacheaveis__
 +        * Seja por segundos, minutos ou dias
 +
 +  * A validação do cache se dá por um processo //​__complexo__//​ chamado **Cache Invalidation** (//​Invalidação de cache//)
 +    * Contudo o protocolo HTTP já possui em seu núcleo __tudo o que é necessário__ para tratar o cache do lado cliente
 +
 +  * //Caching HTTP// visa
 +    * o mínimo possível de envio de requisições ao máximo
 +      * consegue-se por meio do **header**(//​cabeçalho//​) **Cache-Control**
 +    * ou
 +    * reduzir ao mínimo possível os dados da resposta
 +      * consegue-se por meio do mecanismo de validação **ETag** ou **Last-Modified**
 +
 +==== Cache no Cliente ====
 +
 +  * a mais rápida requisição HTTP é o seu envio parcial
 +
 +  * O **header** (//​cabeçalho//​) **Cache-Control** auxilia ​
 +    * na definição de uma política de cache para um recurso
 +
 +^  Cache-Control ​ ^^
 +^  Propriedades ​ ^  Objetivo ​ ^
 +|  **max-age** ​ |  Quantos **segundos** a resposta **ficará** cacheada ​ |
 +|::: | O caching pode ser feito por intermédiarios* |
 +|::: | routers, proxies* e não apenas pelo browser |
 +|  **no-cache** ​ |  A resposta __pode ser__ cacheada ​ |
 +|::: | __checa-se antes o servidor__, para saber se pode ser **reusado** |
 +|::: | pode ser usada em conjunto com uma **Etag** |
 +|  **no-store** ​ |  A resposta __não será armazenada__ ​ |
 +|::: | no browser ou nos intermediários |
 +|  **private** ​ |  Caching __apenas__ pelo browser ​ |
 +|::: | **CDNs** (**C**ontent **D**ellivery **N**etwork),​ por exemplo, não poderiam fazê-lo |
 +|  **public** ​ |  Pode ser feito por qualquer um  |
 +
 +  * Foi listado acima as **principais**
 +
 +  * Mais informações em [[https://​developer.mozilla.org/​en-US/​docs/​Web/​HTTP/​Headers/​Cache-Control| Mozilla - Cache Control]]
 +
 +  * Para testes:
 +
 +    curl -I http://​g1.globo.com/​
 +    curl -I http://​www.uol.com.br/​
 +    curl -I http://​www.submarino.com.br/​
 +
 +  * **Contudo**
 +    * O cabeçalho **Cache-Control** __não funciona__ para //APIs//
 +      * Pois é utilizado, na maior parte, na página inicial de acesso
 +
 +==== ETag ====
 +
 +  * É o **header** (//​cabeçalho//​) utilizado para //caching// em APIs
 +    * Tendo como propósito: a redução dos dados a serem trafegados
 +    * E este curso estará fazendo caching no servidor
 +    * [[https://​developer.mozilla.org/​en-US/​docs/​Web/​HTTP/​Headers/​ETag|Mozilla - ETag]]
 +
 +
 +  * **E**ntity **Tag**
 +    * //Usado para assegurar um __token__ de validação//​
 +    * //​Identificando uma versão espeçífica da resposta//
 +      * Basicamente,​ a resposta devolvido ao cliente vem com uma **id**
 +
 +  * Para validar se houve ou não modificação,​ necessário utilizar-se do header **If-None-Match**
 +    * Que é utilizado para comparar com o valor do //token// existente
 +      * oriundo da //​primeira//​ requisição
 +    * E o novo **token** trazido pelo **ETag** de outras respostas.
 +      * oriundas de requisições //​subsequentes//​ com a adição do cabeçalho **If-None-Match**.
 +    * [[https://​developer.mozilla.org/​en-US/​docs/​Web/​HTTP/​Headers/​If-None-Match|Mozilla - If-None-Match]]
 +
 +  * Se iguais, a resposta virá com //​status-code//:​ **304 - Not Modified**
 +    * Diferentes, //​status-code//:​ **202 - OK**
 +      * Conteúdo __foi atualizado__
 +
 +    curl -I https://​jsonplaceholder.typicode.com/​posts/​1
 +
 +    HTTP/1.1 200 OK
 +    ...
 +    Content-Length:​ 292
 +    ...
 +    Etag: W/"​124-yiKdLzqO5gfBrJFrcdJ8Yq0LGnU"​
 +    ...
 +    ​
 +    {...}
 +
 +    curl -I https://​jsonplaceholder.typicode.com/​posts/​1 -H '​If-None-Match:​ "​124-yiKdLzqO5gfBrJFrcdJ8Yq0LGnU"'​
 +
 +    HTTP/1.1 304 Not Modified
 +    ...
 +    Etag: W/"​124-yiKdLzqO5gfBrJFrcdJ8Yq0LGnU"​
 +
 +=== Token ===
 +
 +
 +  * O //id// que representa a requisição é o **token** utilizado pelo **ETag**
 +    * De acordo com este **token** pode-se saber se o conteúdo foi modificado ou não.
 +
 +  * A representação do **token** pode ser composta por letras e números
 +    * Uma opção então é utilizar um **hash**
 +    * __//Deve-se atentar//​__:​ que o cálculo deste **hash** acrescenta um custo computacional
 +      * Se o referido [[info:​apirest:​start#​resource|Recurso]] for atualizado muitas vezes
 +        * Considere usar outra alternativa diferente de **hash**
 +        * como representação de valor no **ETag**
 +
 +  * Outra opção é o **__timestamp__** do recurso
 +    * como forma de validação se está atualizado ou não
 +    * A implementação seria o valor de um dado de uma coluna do banco de dados
 +      * que indica a última atualização do referido registro
 +  * Neste caso, necessário utilizar o cabeçalho **Last-Modified**,​ ao invés do **ETag**
 +    * e para validação,​ incluir o cabeçalho **If-Modified-Since**
 +
 +=== HTTP Condicionais ===
 +
 +  * Existe uma variedade de opções de cabeçalhos (//​headers//​)
 +    * que permitem o uso de HTTP Condicionais
 +    * [[https://​developer.mozilla.org/​en-US/​docs/​Web/​HTTP/​Conditional_requests|Mozilla - Requisições Condicionais]]
 +
 +==== Diferentes representações ====
 +
 +  * Relembrando: ​
 +    * Para solicitar requisições com diferentes [[info:​apirest:​start#​representacoes|representações]]/​[[info:​apirest:​start#​tipo_de_midia|Tipo de mídia]]
 +    * Necessário informar o **header** (//​cabeçalho//​) **Accept**
 +
 +  * Porém, o navegador
 +    * Usa o [[info:​apirest:​start#​metodos_verbos_http|método HTTP]] e a [[info:​apirest:​start#​uri|URI]]
 +    * para **registrar** respostas cacheadas
 +    * Ou seja, **mesmo** verbo e URI
 +      * o navegador não saberá o que cachear
 +
 +  * Para resolver, utiliza-se o **header** (//​cabeçalho//​) **Vary**
 +    * Dessa forma, o navegador passa a cachear utilizando-se de
 +      * Verbo
 +      * URI
 +      * Representação (indicada pelo //header// **Accept**)
 +
 +    curl -I https://​jsonplaceholder.typicode.com/​posts/​1 -H "​Accept:​ application/​json" ​
 +
 +    ...
 +    Vary: Origin, Accept-Encoding ​
 +    ...
 +
 +  * Outros headers como:
 +    * **Accept-Language**
 +    * **Accept-Encoding**
 +      * se estiverem disponíveis
 +      * também irão compor o mecanismo acima, usado pelo navegador,
 +      * e tais recursos estarão cacheados, distintamente
 +
 +  * Para mais informações [[https://​developer.mozilla.org/​en-US/​docs/​Web/​HTTP/​Headers/​Vary|Mozilla - Vary]]
 +
 +
 +===== Autenticação =====
 +
 +  * Visa identificar quem está fazendo acesso a um recurso
 +    * e se possui permissão para acessá-lo
 +
 +  * Costuma-se nas aplicações web utilizar-se de **cookies**
 +    * para gerenciar as autenticações
 +    * [[https://​tools.ietf.org/​html/​rfc6265| RFC 6265 - HTTP State Management Mechanism (HTTP Cookie)]]
 +
 +  * Os **cookies** eram utilizados para 
 +    * gravar
 +    * e manter
 +      * os __estados__ (//​stateful//​)
 +  * Contudo o **REST**
 +    * é [[info:​apirest:​start#​stateless|stateless]]
 +      * **//Uma requisição não depende da outra//**.
 +
 +
 +  * É por meio do [[info:​apirest:​start#​stateless|stateless]]
 +    * Que aplicações web tornam-se
 +      * mais **//​escaláveis//​**
 +      * e de fácil **//​caching//​**
 +
 +  * O HTTP tem como esquema de autenticação ​
 +    * o padrão **Basic** - [[https://​tools.ietf.org/​html/​rfc7617| RFC 7617 - The '​Basic'​ HTTP Authentication Scheme]] / [[https://​developer.mozilla.org/​en-US/​docs/​Web/​HTTP/​Authentication| Mozilla - Authentication]]
 +    * E **Digest** - [[https://​tools.ietf.org/​html/​rfc2617|RFC 2617 - HTTP Authentication:​ Basic and Digest Access Authentication]]
 +      * O problema é que em ambas
 +      * __sempre será solicitado autenticação__ nas requisições
 +
 +  * A solução encontrada para uso em APIs é o uso de 
 +    * **API Key** ou **API Secret Token**
 +      * //​Aplicação que **consome** API// ⇔ __//secret token//__ ⇔ //​Aplicação que **serve** API//
 +      * É uma string ​ de letras e números
 +      * Transmitida em todas as requisições
 +        * que identifica a aplicação
 +      * Combinada com e-mail ou senha, ou ambos dependendo da aplicação
 +
 +  * **<color #​ed1c24>​Importante</​color>​**
 +    * Tais dados **precisam** estar sendo trafegados em uma __conexão segura__
 +    * Para tal é necessário que o servidor da API esteja usando **__certificados SSL__**
 +      * Como opção de implementação,​ hoje existe a solução livre [[https://​letsencrypt.org/​|Let’s Encrypt]]
 +
 +  * Assim, a opção mais utilizada costuma ser
 +    * Login e senha do usuário solicitados e autenticados
 +      * com sucesso ⇒ //**token** de identificação//​ é retornado
 +      * ou não autenticados ​ ⇒ **401 - UNAUTHORIZED**
 +
 +  * Diferença entre:
 +
 +
 +^  Identificação ​ ^  Autenticação ​ ^  Autorização ​ ^
 +|  Exemplo: Google Maps  |  Exemplo: Login/​Senha ​ |  -  |
 +|  API Key  |  Comprova-se a identidade de quem acessa ​ |  Verifica quais ações que podem ser executadas por quem acessa ​ |
 +|  Possivelmente vinculada a um tipo de cadastro ​ |  -  |  Costuma utilizar-se dos outros dois: identificação,​ autenticação ​ |
 +|  Pode-se fazer restrições de uso  |  -  |  |
 +|  Pode ser reutilizada por outros ​ |  -  |  |
 +
 +==== Autenticação com HTTP ====
 +
 +  * Dois tipos de autenticação disponibilizados pelo HTTP:
 +    * **Basic**
 +      * codifica-se em **Base64**
 +    * **Digest** (//​resumida//​)
 +      * codifica-se em **MD5**
 +
 +    * Usuário e senha são incluídos em cada requisição
 +      * e codificados nos específicos formatos acima
 +    * Ambas seguem a constraint REST [[info:​apirest:​start#​stateless|stateless]]
 +
 +  * Conforme a documentação,​ para haver a autenticação necessário enviar o **header** ​
 +    * //​Authorization:​ auth-scheme hashed-credentials//​
 +    * Sendo //​auth-scheme//​
 +      * **Basic**
 +      * ou **Digest**
 +    * e //​hashed-credentials//​
 +      * o e-mail e senha codificados no respectivo formato
 +
 +    Authorization:​ Basic am9objpwYXNz
 +
 +  * para requisição via cURL:
 +
 +    curl -u usuario:​senha http://​minha.api.com
 +
 +  * Este parâmetro já converte o usuário e senha para a respectiva **Base64**
 +    * e inclui o header **//​Authorization//​** no formato indicado acima
 +
 +  * Para uso do padrão **Digest**, adiciona-se mais um parâmetro:
 +
 +    curl --digest -u usuario:​senha http://​minha.api.com
 +
 +  * A resposta do servidor será feito com a inclusão da **header** (//​cabeçalho//​)
 +    * //​WWW-Authenticate//​
 +      * que indica o tipo de autenticação usado
 +      * e o domínio (//​**realm**//​)
 +        * esta diretiva é **opcional**
 +        * apenas indica qual é área que está sendo feito acesso
 +        * pois diferentes áreas podem utilizar-se de outras autenticações
 +
 +    WWW-Authenticate:​ Basic realm="​Perfil"​
 +
 +==== Autenticação baseada em Token ====
 +
 +  * Relembrando que nesta autenticação
 +    * é feito o envio de //​usuário//​ e //senha// para o servidor
 +      * __não será utilizado__ a **header** //​Authorization//​
 +      * mas o formulário comum html
 +
 +  * No servidor é feita a autenticação
 +      * que tendo __sucesso__,​ a resposta é devolvido com um **token**
 +        * que será utilizado como autenticação nas requisições subsequentes.
 +          * aí sim, usando a **header** //​Authorization//​
 +      * ou o erro **401 - UNAUTHORIZED** se autenticação __falha__.
 +
 +  * o envio de dados com cURL deverão ser feitos no formato abaixo:
 +
 +    curl http://​minha.api.com/​login \
 +            -i -d '​{"​email":"​meu@usuario.com",​ "​password":​ "minha senha"​}'​
 +
 +  * O retorno, como exemplo, seria algo similar a:
 +
 +    HTTP/1.1 200 OK
 +    Content-Type:​ application/​json
 +    Content-Length:​ 51
 +    ...
 +
 +    {"​auth_token":"​6afc7f5db9eaaf7eab"​}
 +
 +  * Com este //​message-body//,​ as próximas requisições seriam feitas no seguinte formato:
 +
 +    curl -i -H '​Authorization:​ Token 6afc7f5db9eaaf7eab'​ https://​minha.api.com
 +
 +  * Contudo, isso pode implicar no armazenamento do token
 +    * o que fere a **constraint** [[info:​apirest:​start#​stateless|stateless]]
 +
 +  * E como já dito anteriormente,​ na necessidade de __escalar a aplicação__ pode-se surgir dificuldades,​ pois
 +    * dados serão **replicados** conforme é feito esta escalabilidade ​
 +      * //​identificação//​ do token por cada servidor
 +    * muitos tokens para serem **gerenciados**,​ de acordo com o aumento do número de requisições/​tráfego ​
 +      * principalmente se __houver mais de um__ token por requisição
 +
 +==== Autenticação Stateless ====
 +
 +  * Duas opções:
 +    * [[https://​oauth.net/​|OAuth]]
 +    * [[https://​jwt.io/​|JWT]]
 +
 +
 +  * O **OAuth** é muito utilizando por diversas páginas e aplicações (web, mobile etc)
 +
 +  * Basicamente,​ quando chega-se a uma página que possui autenticação **OAuth**
 +    * E solicita-se fazer cadastro na mesma, esta oferece algumas opções de autenticação
 +      * Como Google
 +      * Facebook
 +      * Twitter etc
 +    * Ao escolher uma delas, esta página está retornando um **token** e redirecionando-o
 +      * para a respectiva página da autenticação escolhida
 +      * Nesta página, será solicitado que se faça o login 
 +        * (se já não estiver feito)
 +      * e então é solicitado a confirmação da autorização do uso do login para a página inicial.
 +    * Quando confirma-se a autorização, ​
 +      * __**outro**__ **token** é devolvido
 +      * e redireciona-o a origem (a página inicial)
 +  * A página inicial recebe o __**novo**__ **token**
 +    * Consulta no serviço de autenticação escolhido nos passos iniciais
 +      * se aquele **token** foi realmente lá gerado
 +    * E se confirmado, a página inicial terá o acesso finalmente liberado
 +
 +  * Este procedimento também é conhecido como autenticação **//​[[https://​www.ibm.com/​support/​knowledgecenter/​en/​SS9H2Y_7.6.0/​com.ibm.dp.doc/​oauth_threeleggedflow.html|OAuth Three-legged]]//​**
 +    * ou autenticação //OAuth em 3 passos// (rusticamente traduzido).
 +
 +  * Vantagem mais visível: **Escalabilidade**
 +    * O token não é mais armazenado pela página acessada.
 +    * Ela sempre consultará o serviço de autenticação escolhido
 +      * sendo este quem passa a fazer o gerenciamento do token criado
 +
 +  * Ainda assim, não há na verdade um consenso se isto é realmente **Stateless**
 +    * Alguns afirmarão que sim, pois a página acessada não armazena o token
 +      * E o consulta por outro recurso
 +    * Outros afirmarão que existe o armazenamento,​ mesmo que não local
 +      * e isso fereria a **constraint**
 +
 +  * Leituras sugeridas:
 +    * [[https://​scotch.io/​tutorials/​the-ins-and-outs-of-token-based-authentication]]
 +    * [[http://​www.kaleidos.net/​blog/​295/​stateless-authentication-with-api-rest/​]]
 +
 +==== Autenticação JWT ====
 +
 +  * **J**SON **W**eb **T**okens - [[https://​jwt.io/​|JWT]]
 +    * [[https://​tools.ietf.org/​html/​rfc7519|RFC 7519 - JSON Web Token (JWT)]]
 +      * "//​JSON Web Token (JWT) é um padrão aberto (RFC 7519) que define um meio compacto e auto-contido para transmissão segura de informação entre partes por meio de um objeto JSON//"​
 +
 +  * Busca resolver a deficiência de manter os dados da autenticação(**token**) em um servidor
 +    * mesmo que seja de terceiros ([[info:​apirest:​start#​autenticacao_stateless|OAuth]])
 +    * pois fere a constraint [[info:​apirest:​start#​stateless|stateless]]
 +
 +  * E o meio encontrado é que ao invés de manter o **token** em algum servidor
 +    * o **token** é deixado com o __próprio cliente__.
 +
 +{{https://​cdn.auth0.com/​content/​jwt/​jwt-diagram.png|Origem:​ https://​jwt.io/​introduction/​}}
 +
 +=== Estrutura JWT ===
 +
 +  * //​hhhhhh.pppppp.ssssss//​
 +    * [[https://​jwt.io/​introduction/​|JWT - Introdução]]
 +
 +^  Header ​ ^  Payload ​ ^  signature ​ ^
 +|  //​hhhhhh// ​ |  //​pppppp// ​ |  //​sssssss// ​ |
 +|  definidos no formato JSON  ||   ​chave-secreta ​  |
 +|  indica o algoritmo de hashing ​ |  //carga útil do **token**// ​ |  Dá validade ao **header** e ao **payload** ​ |
 +|  indica o tipo de **token** ​ |  define-se as reinvidicações(//​**claims**//​),​ entidades e metadados ​ |  Apenas o servidor a gera  |
 +|  [[http://​www.motobit.com/​util/​base64-decoder-encoder.asp|Ferramenta Base64 Decoder-Encoder ]]  |  os **claims** podem ser registrados,​ públicos ou privadas ​ |  |
 +
 +  * Exemplo:
 +
 +{{https://​cdn.auth0.com/​blog/​legacy-app-auth/​legacy-app-auth-5.png|Origem:​ https://​jwt.io/​introduction/​}}
 +
 +  * Leituras sugeridas:
 +    * [[https://​blog.imaginea.com/​stateless-authentication-using-jwt-2/​]]
 +
 +===== JSON API =====
 +
 +  * [[http://​jsonapi.org/​]]
 +    * Recomendação de uso para construção da própria API
 +
 +===== Documentação API =====
 +
 +  * [[https://​swagger.io/​]]
 +    * Ferramenta/​utilitário usado para documentação da API
 +      * Também possibilita a geração de código tanto
 +        * para o lado cliente
 +        * quanto para o lado servidor
 +
 +  * [[https://​stackoverflow.com/​a/​46484079|Como converter a página do Swagger em HTML]]
 +    * Ferramenta que possibilita a conversão: [[https://​gist.github.com/​oseiskar/​dbd51a3727fc96dcf5ed189fca491fb3|swagger-yaml-to-html.py]]
 +
 +
 +----
 +
 +
 +[[disqus:​start|{{ https://​a.disquscdn.com/​dotcom/​d-2407bda/​img/​brand/​disqus-social-icon-white-blue.png?​80x60|Deixe seu comentário}}]]
© 2019 por Samuel