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/ |  Visualizar  |
 +|  POST  |  /savePosts  |  Criar  |
 +|  POST  |  /updatePosts/ |  Alterar  |
 +|  GET/POST  |  /delPosts/ |  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/ |  Visualizar  |
 +|  POST  |  /posts  |  Criar  |
 +|  PUT  |  /posts/ |  Alterar  |
 +|  DELETE  |  /posts/ |  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}}]]
© 2020 por Samuel