中文版 | 日本語版 | 한국어 | РУССКИЙ | ENGLISH
Enquanto desenvolver um novo projeto é apenas diversão para você, manter esse projeto pode ser um dos piores pesadelos para outra pessoa. Isso aqui é uma lista dos padrões que encontramos, coletamos e escrevemos que (para nós) funcionam realmente bem com a maioria dos projetos JavaScript aqui na elsewhen. Se você quer compartilhar alguma prática que considera importante ou acha que alguma das coisas descritas aqui deve ser removida, Sinta se a vontade para nos dizer.
🔥 Confira nosso react redux projeto base em Flow com hot reloading e server-side rendering.
- Padrões de Projeto ·
Essas são algumas regras do Git para manter em mente:
-
Trabalhe em uma feature branch.
Por que?:
Porque desse jeito todo o código é criado isolado em uma branch específica ao invés de poluir a branch principal com trabalho em progresso. Isso vai permitir você abrir vários pull requets sem confusão. Você pode continuar com uma branch em progresso sem correr o risco de quebrar a branch principal com código instável. Leia mais sobre...
-
Sempre comece uma nova branch a partir da
develop
Por que?
Desse jeito você pode garantir que o código na master vai estar sempre pronto para fazer build sem problemas e poderá ser usado a qualquer momento para fazer releases (isso pode ser exagero para alguns projetos).
-
Nunca dê push direto na
develop
oumaster
. Sempre faça Pull Requests.Por que?
Isso permite outros membros do time saberem que você terminou uma feature. Também possibilita code review e dicussões sobre o código que está prestes a ser introduzido no code base.
-
Atualize sua
develop
local e faça rebase interativo antes de subir sua feature e abrir um Pull Request.Por que?
Rebase vai fazer um merge do branch destino do pull request e aplicar os commits que você tem localmente no topo da história sem criar um commit de merge (assumindo que não tem conflitos). Como resultado você tem uma história limpa no seu repositório. Leia mais sobre ...
-
Resolva os conflitos enquanto faz o rebase e antes de abrir o Pull Request.
-
Delete feature branches, local e remoto, depois de realizar o merge.
Por que?
Vai reduzir sua lista de branches removendo branches mortas. Vai garantir que você apenas faça o merge de uma branch uma única vez. Feature branches só devem existir enquanto o código ainda está em progresso.
-
Antes de fazer um Pull Request, tenha certeza que sua feature branch está fazendo build corretamente e passando em todos os testes (incluindo os padrões de estilo de código).
Por que?
Você está prestes a colocar seu código em uma branch estável. Se sua feature branch faz algum teste falhar, a chance é alta de que você vai quebrar o build na branch destino. Você também precisa conferir o code style antes de fazer um Pull Request. Isso contribui para legibilidade e reduz a chance de algum problema de formatação is para o code base com as outras alterações.
-
Faça uso desse
.gitignore
.Por que:
É uma lista que já contém arquivos de sistemas que não devem ser enviados para o seu repositório remoto. E também exclui pastas de configuração e os arquivos comumente usado por editores e obviamente, também, pastas de dependência.
-
Proteja (Bloqueie) a
develop
emaster
.Por que?
Protege suas branchs que devem, em teoria, estarem prontas para irem para produção de receberem códigos e mudanças irreversíveis. Leia mais sobre... Github, Bitbucket e GitLab
Devido a maioria dos motivos listados acima, nos usamos Feature-branch-workflow com Interactive Rebasing e alguns pontos do Gitflow (nomeação e ter uma develop branch). Os principais passos são:
-
Em um projeto novo, inicialize o git na pasta do projeto. Para qualquer features/changes ignore esse passo.
cd <pasta do projeto> git init
-
Checkout para uma nova branch feature/bug-fix.
git checkout -b <branchname>
-
Faça as alterações.
git add <arquivo1> <arquivo2> ... git commit
Por que?
git add <arquivo1> <arquivo2> ...
- Você deve add apenas arquivos com mudanças pequenas e concisas.git commit
Abrirá o editor, o que permite você separar o titulo da mensagem.Leia mais sobre na seção 1.3.
Dica:
Você poderia usar
git add -p
, o que te daria a chance de revisar todas as mudanças introduzidas, uma a uma, e decidir se inclui ou não naquele commit. -
Sincronize com as ultimas alterações no repositório remoto.
git checkout develop git pull
Por que?
Isso vai permitir que você lide com os conflitos na sua máquina local enquanto você faz o rebase (posteriormente) ao invés de criar um pull request com conflitos.
-
Atualize sua feature branch com as ultimas alterações da develop usando rebase iterativo.
git checkout <branchname> git rebase -i --autosquash develop
Por que?
Você pode usar --autosquash para comprimir todos os seus commits em um único commit. Ninguém quer commits de desenvolvimento de uma feature na develop. Leia mais sobre...
-
Se você não tem conflitos, pule esse passo. Se você tem conflitos, resolva-os e continue onrebase.
git add <file1> <file2> ... git rebase --continue
-
Push sua branch. Rebase vai alterar a história, então você precisa usar
-f
para forçar a mudança no branch remoto. Se tem mais alguém trabalhando na mesma branch, use o comando--force-with-lease
.git push -f
Por que?
Quando você faz rebase, você está mudando a história na sua feature branch. Então o git ira rejeitar seu
git push
. Para passar por isso você precisa usar -f ou --force flag. Leia mais sobre... -
Abra um Pull Request.
-
Pull request deve ser aceito, mergiado e fechado por quem estiver revisando.
-
Delete seu branch local se tiver terminado.
git branch -d <nome do branch>
Para remover todos os branchs que não existem no repositório remoto:
git fetch -p && for branch in `git branch -vv --no-color | grep ': gone]' | awk '{print $1}'`; do git branch -D $branch; done
Ter um bom padrão para criar commits e se atentar a ele faz com que trabalhar com Git e colaborar com outros seja muito mais fácil. Aqui estão algumas boas práticas (fonte):
-
Separe o assunto e a mensagem com uma nova linha entre eles.
Por que?
Git é inteligente o suficiente para identificar a primeira linha do seu commit como um resumo. Na verdade, se você tentar shortlog, ao invés de git log, você vai ver uma longa lista de mensagens de commits, com apenas o id e o resumo do commit.
-
Máximo de 50 caracteres para o assunto e 72 para a mensagem.
Por que?
Commits devem ser objetivos e claros, não é o momento para ser verboso. Leia mais sobre...
-
Capitalize a linha do assunto.
-
Não use um ponto para finalizar a linha do assunto.
-
Use imperative mood na linha do assunto.
Por que?
É melhor que o commit diga o que vai acontecer no projeto depois daquele commit do que o que o que aconteceu dentro do commit em si. Lei mais sobre...
- Use a mensagem para explicar o que e porque ao invés de como.
- Use esse template para
README.md
, sinta-se a vontade para adicionar seções que achar necessárias. - Para projetos com mais de um repositório adicione todos os respctivos links nos
README.md
de todos os projetos. - Mantenha o
README.md
enquanto o projeto evolui. - Comente seu código. Tente sempre deixar claro o que uma grande parte do código tem a intenção de fazer.
- Se existe alguma referência em relação a forma como você resolveu o problema ou uma discussão em aberto, adicione os links.
- Não use comentários como desculpa para fazer um código ruim. Mantenha seu código limpo.
- Não use código limpo como uma desculpa para não fazer nenhum comentário.
- Mantenha apenas os comentários relevantes enquanto o código evolui.
-
Defina ambientes de
desenvolvimento
,testes
eprodução
separados.Por que?
Diferentes informações, dados, tokens, APIs, portas etc... podem ter que ser diferentes em cada ambiente. Você provavelmente vai querer isolar seu ambiente de
desenvolvimento
para fazer chamadas fake para a API que retornará dados previsíveis, tornando tanto os testes automatizados quanto os manuais muito mais facéis. Ou você pode querer ativar o Google Analytics apenas emprodução
e etc... Leia mais sobre...
-
Carregue suas configurações específicas de deploy de variáveis de ambiente e nunca as adicione no seu codebase como constantes, veja aqui um exemplo.
Por que?
Você terá tokens, senhas e outras informações sigilosas nessa configuração. Sua configuração deve ser corretamente separada da sua aplicação como se seu codebase pudesse se tornar público a qualquer momento.
Como?
Arquivos
.env
para manter suas variáveis e então adicione-o ao.gitignore
para ser excluído. Ao invés, commit um.env.example
que servirá de modelo para outros desenvolvedores. Para produção, você deve setar suas variáveis no jeito padrão. Leia mais sobre... -
É recomendável validar suas variáveis de ambiente antes de inicializar sua aplicação. De uma olhada nesse exemplo usando
joi
para validar os valores.Por que?
Pode salvar todos de horas de "dor de cabeça".
-
Defina sua versão do node em
engines
nopackage.json
.Por que?
Permite que todos saibem em qual versão o projeto funciona. Leia mais sobre...
-
Adicionalmente, use
nvm
e crie um arquivo.nvmrc
na raíz do seu projeto. Não se esqueça de menciona-lo na sua documentação.Por que?
Qualque pessoa que usar
nvm
pode apenas rodarnvm use
para trocar para a versão correta. leia mais sobre... -
É uma boa ideia criar um script
preinstall
para conferir as versões do node e do npm.Por que?
Algumas dependências podem falhar quando instaladas por versões mais recentes do NPM.
-
Use Docker se puder.
Por que?
Te dará um ambiente estável durante todo o workflow. Sem muita necessidade de lidar com dependências e configurações. leia mais sobre...
-
Use local modules ao invés de modules instalados globalmente.
Por que?
Você estará compartilhando suas dependências com os outros ao invés de esperar que eles a tenham instalado globalmente.
-
Garanta que seus colegas de equipe obtenham exatamente a mesma versão de dependências que você.
Por que?
Porque você quer que se código tenha o mesmo comportamento em qualquer máquina de desenvolvimento leia mais sobre...
Como?
Use
package-lock.json
a partir donpm@5
E se eu não tenho npm@5?
Uma alternativa pode ser o
Yarn
e não se esqueça de mencionar o seu uso noREADME.md
. Seu lock file e opackage.json
devem manter as mesmas versões após cada atualização. leia mais sobre...E se eu não gosto do nome
Yarn
?Que pena. Para versões antigas do
npm
, use—save --save-exact
quando instalando novas dependências e criando umnpm-shrinkwrap.json
antes de publicar. Leia mais sobre...
-
Acompanhe seus pacotes disponíveis atualmente: e.g.,
npm ls --depth=0
. Leia mais sobre... -
Confira se algum dos seus pacotes não está em uso ou se tornou irrelevante:
depcheck
. Leia mais sobre...Por que?
Você pode estar fazendo o bundle final ficar maior com bibliotecas não usadas. Identifique essas bibliotecas não usadas e se livre delas.
-
Antes de começar a usar uma dependência, confira o quanto ela é usada pela comunidade:
npm-stat
. Leia mais sobre...Por que?
Maior uso geralmente significa mais contribuidores, o que leva a deduzir que possui melhor manutenção, o que tudo isso junto leva a concluir que bugs serão encontrados mais facilmente e resolvidos rapidamente.
-
Antes de usar uma dependência, confira se possui uma versão madura o suficiente com um grande número de pessoas mantendo: e.g.,
npm view async
. Leia mais sobre...Por que?
Ter muitos contribuidores não var ser tão efetivo se os mantenedores não fizerem os merge fixes e patches rápido.
-
Se você precisa de uma dependência menos conhecida, discuta com o time antes de usa-la.
-
Sempre tenha certeza que sua aplicação funciona com a ultima versão das dependências:
npm outdated
. Leia mais sobre...Por que?
Atualização de dependência as vezes possuem 'breaking changes'. Sempre confira a descrição da nova versão sempre que sair, isso faz com que lidar com os possíveis problemas seja mais fácil. Use uma dessas ferramentas maneiras, como: npm-check-updates.
-
Confira problemas de segurança com a dependência que você quer adicionar, e.g., Snyk.
-
Tenha um ambiente the
test
se necessárioPor que?
Embora algumas vezes testes end to end em
produção
possam parecer suficientes, existem algumas exceções: Um exemplo é que você não vai querer colocar dados analíticos emprodução
e assim poluir o dashboard de alguém com dados de teste. Outro exemplo é que sua API pode ter algumas limitações enquanto emprodução
e chamadas de teste depois de uma certa quantidade. -
Coloque os arquivos de teste junto com os arquivos a serem testados usando a convenção
*.test.js
ou*.spec.js
para nomear os arquivos, comomoduleName.spec.js
.Por que?
Você não quer ter que navegar em várias pastas para achar um teste unitário. Leia mais sobre...
-
Coloque seus arquivos de testes adicionais em uma pasta separada para evitar confusão.
Por que?
Alguns arquivos de testes não tem nenhuma relação com qualquer outro arquivo. Você deve coloca-los em uma pasta fácil de ser encontrada pelos outros desenvolvedores do time, como por exemplo: Uma pasta
__test__
. Essa nomeação é padrão e reconhecida pela maioria de frameworks de teste de JavaScript. -
Escreva código testável, evite efeitos colaterais (side effects), escreva funções puras
Por que?
Você vai querer testar uma regra de negócio como uma unidade separada. Voce tem que "minimizar o impacto de aleatoriedade e processos não determinísticos no seu código". Leia mais sobre...
Uma função pura é uma função que sempre retorna o mesmo valor para uma entrada específica. Por outro lado, uma função impura é uma função que pode ter efeitos colaterais e depender de condições externas para retornar algum valor. Isso reduz a capacidade de prever o que o código vai realizar. Leia mais sobre...
-
Use uma checagem de tipo estática
Por que?
As vezes você vai precisar de checagem de tipo estática. O que também aumenta a regidibilidade e legibilidade do seu código. Leia mais sobre...
-
Rode os testes localmente antes de abrir um pull request para
develop
.Por que?
Você não quer ser a pessoa a fazer com que a branch com código pronto para produção pare de funcionar. Rode seus teste depois que fizer
rebase
e antes de fazer push para sua feature branch. -
Documente seus testes incluindo instruções importantes em uma seção no arquivo
README.md
.Por que?
Vai ser de muita ajuda para outros desenvolvedores, DevOps, QA ou qualquer um que tiver a sorte de trabalhar com seu código.
-
Organize seus arquivos considerando feature / páginas / componentes. E também, coloque os arquivos de teste próximos à implementação..
Ruim
. ├── controllers | ├── product.js | └── user.js ├── models | ├── product.js | └── user.js
Bom
. ├── product | ├── index.js | ├── product.js | └── product.test.js ├── user | ├── index.js | ├── user.js | └── user.test.js
Por que?
Ao invés de uma longa lista de arquivos você estará criando pequenos modulos encapsulando responsabilidades e seus respectivos testes. Fica muito mais fácil de se navegar e as coisas podem ser facilmente encontradas.
-
Use uma pasta com o nome
./config
e não crie arquivos de configuração diferente para cada ambiente.Por que?
Quando você distribuí as configurações em arquivos com propósitos diferentes (database, API e etc); Coloca-los em uma pasta com o nome fácil de reconhecer como
config
faz sentido. Apenas se lembre de não criar arquivos de configuração diferentes para cada ambiente. Isso não escala, cada novo deploy diferente que se faz necessário, novos nomes de ambientes são criados. Valores para serem usados por arquivos de configuração devem ser providos através de variáveis de ambiente. Leia mais sobre...
-
Coloque seus scripts em uma pasta nomeada
./scripts
. Isso vale parabash
enode
.Por que?
É bem provável que você vai acabar com mais de um script, build de produção, build de dev, database feeders, database sync e etc...
-
Direcione os arquivos de output do build em uma pasta nomeada
./build
. Adicionebuild/
no.gitignore
.Por que?
Dê o nome que você achar conveniente,
dist
também é uma boa opção. Mas tenha a certeza de manter isso consistente com os projetos do time. Os arquivos que vão para essa pasta são gerados automaticamente (bundled, compiled, transpiled) ou movidos automaticamente para lá. O que você pode gerar, qualquer um no time deve ser capaz de gerar também, então não faz nenhum sentido comitar isso para o repositório. A não ser que você realmente queira muito fazer isso.
-
Use stage-2 e sintaxe moderna de JavaScript nos seus novos projetos. Para os projetos antigos, mantenha a consistência, a não ser que modernizar o projeto seja o objetivo.
Por que?
É claro, isso só depende de você. Nós usamos transpilers para tirar vantagem de novas sintaxes. stage-2 é bem provável de se tornar parte da especificação em alguma revisão.
-
Inclua alguma conferência automática de padrão de código no seu build.
Por que?
Quebrar o build é uma forma de forçar os padrões de código. Evite que não seja levado a sério. Faça isso tanto para o backend quanto para o front. Leia mais sobre...
-
Use ESLint - Pluggable JavaScript linter para garantir que os padrões serão seguidos.
Por que?
Nós simplesmente preferimos
eslint
, você não precisa necessariamente o usar. Ele tem mais regras suportadas, a possibilidade de configura-las e criar regras customizadas. -
Nós usamos Airbnb JavaScript Style Guide para JavaScript, Leia mais sobre. Escolha os padrões necessário para seu projeto.
-
Usamos Flow type style check rules for ESLint ao usar FlowType.
Por que?
Flow usa algumas sintaxes que também precisam de seguir um padrão.
-
Use
.eslintignore
para excluir os arquivos que devem ser ignorados pelas regras.Por que?
Você não precisa poluir seu código com comentários como
eslint-disable
toda vez que quiser desabilitar alguma regra em um certo arquivo. -
Remova todos
eslint-disable
antes de fazer um pull request.Por que?
É normal desabilitar o
eslint
para focar na lógica de uma parte do código. Apenas se lembre de remover oeslint-disable
quando terminar. -
Dependendo do tamanho da task, use comentários com
//TODO:
para ajudar na criação de novas tasks para o backlog.Por que?
Você vai deixar um lembrete para os outros, e para você mesmo, de pequenas tarefas ou correções (como refatorar uma função ou atualizar um comentário). Para tarefas maiores escreva
//TODO(#3456)
fazendo referência ao ticket aberto no backlog para aquela task.
-
Sempre faça comentários relevantes. Delete código morto ou comentado.
Por que?
Você deve prezar pela legibilidade do seu código, então se livre de qualquer distração possível no código. Se você refatorou uma função, não deixe a antiga lá apenas comentada, delete-a.
-
Evite comentários irrelevantes, engraçados ou ofensivos.
Por que?
Mesmo que seu processo de build possa remove-los, as vezes seu código pode ser pego por alguém diferente, uma empresa terceirizada ou um chefe de outra área e isso pode não ser tão tranquilo.
-
Use nomes com significados, fáceis de pesquisar e sem abreviações para suas variáveis ou funções. O nome de uma função deve ser um verbo ou uma frase e precisa de deixar claro a sua intenção.
Por que?
Faz com que o seu código seja mais legível e natual.
-
Use o arquivo .editorconfig para ajudar a definir e manter a consistência de estilo de código entre diferentes editores e IDE.
Por que?
O EditorConfig consiste em um arquivo para edição de estilo de código e declaração de plugins para habilitar o editor a ler os arquivos em um determinado formato e formatá-los de acordo com o esperado. EditorConfig são fáceis de ler e funcionam muito bem com sistemas de controle de versão.
-
Configure seu editor para alertar sobre erros de estilo de código. Use eslint-plugin-prettier e eslint-config-prettier com seu arquivo ESLint já existente. Leia mais sobre...
-
Considere usar Git Hooks.
Por que?
Git hooks aumentam de forma expressiva a produtividade do desenvolvedor. Faça alterações, commit e push sem o medo de quebrar o código pronto para produção. Leia mais sobre...
-
Use Prettier com o precommit hook.
Por que?
O
prettier
por si só pode ser bem poderoso porém, não é muito produtivo rodar uma npm task sozinha toda hora só para formatar o código. É então que olint-staged
(e ohusky
) entram em ação. Leia mais sobre como configurar olint-staged
aqui e sobre ohusky
aqui.
-
Evite console logs no client-side em produção
Por que?
Mesmo que o seu processo de compilação possa (e deva) se livrar deles, certifique-se de que seu lint de código avise sobre os console logs restantes.
-
Crie logs de produção legíveis. O ideal é utilizar bibliotecas de log em produção (como, por exemplo winston ou node-bunyan).
_Por que?_ > Ele torna sua solução de problemas mais agradável com sistema de cores, data e hora, registra em um arquivo além do console e até mesmo pode atualizar o arquivo diariamente. [saiba mais...](https://blog.risingstack.com/node-js-logging-tutorial/)
Por que?
Queremos promover o desenvolvimento de RESTful interfaces bem construídas, fazendo com que o consumo por clientes e pelo time seja simples e consistente.
Por que?
Falta de consistência e simplicidade podem aumentar de forma expressiva os custos de manutenção e integração. E por isso
API design
está nesse documento.
-
Devemos seguir o padrão orientado a recursos. O qual tem 3 principais fatore: recursos, coleções, e URLs.
- Um recurso possui dados, gets aninhados, e methods para permitir operações.
- Um grupo de recursos é chamado coleção.
- URL identifica a localização online de um recurso ou coleção.
Por que?
Esse é um padrão muito bem conhecido por desenvolvedores (os principais consumidores de sua API). Fora o fato de ser fácil de usar e ler, permite-nos escrever bibliotecas genéricas e conectores sem ao menos precisar saber sobre o que a API é.
-
use kebab-case para as URLs.
-
use camelCase para os parâmetros na query string ou campo de recursos.
-
use o plural do kebab-case nome dos recursos na URL.
-
Sempre use o plural para nomear algum recurso na URL ou coleção:
/users
.Por que?
Basicamente, é melhor para ler e torna a URL mais consistente. Leia mais sobre...
-
No código fonte, converta plurais para variáveis e propriedades com uma lista de sufixos.
Por que?
Plural é interessante para URLs mas no código é muito sucetível a erros.
-
Sempre use um conceito singular que comece com a coleção e termine com um identificador:
/students/245743 /airports/kjfk
-
Evite URLs como:
GET /blogs/:blogId/posts/:postId/summary
Por que?
Isso não está apontando para um recurso mas, para uma propriedade. Você pode passar a propriedade como um parâmetro para encurtar a resposta.
-
Matenha as URLs de recursos sem verbos.
Por que?
Porque se você usar verbos para cada operação em um recurso você vai acabar com uma lista enorme de URLs e nenhum padrão consistente, o que torna difícil para desenvolvedores lerem. Além disso, nos usamos verbos para outra situação.
-
Use verbos para 'não recursos'. Nesse caso, sua API não retorna nenhum recurso. Ao invés, você executa uma operação que retorna um resultado. Essas não são operações de um CRUD (criar, ler, atualizar, e deletar):
/translate?text=Hallo
Por que?
Porque para CRUD nos usamos os métodos HTTP nos
recursos
oucoleções
. Os verbos que estamos falando são literalmenteControllers
. Você geralmente não chega a desenvolver muito deles. Leia mais sobre... -
Use
camelCase
para as propriedades noJSON
das requisições e da repostas do servidor para manter a consistência.Por que?
Esse é um padrão de projeto para JavaScript, onde a linguagem usada para gerar e parsear JSON é, em teoria, JavaScript.
-
Mesmo que um recurso seja um conceito singular, similar à uma instância ou registro do banco de dados, você não deve usar
nome_da_tabela
para o nome de um recurso enome_da_coluna
para a propriedade de um recurso.Por que?
Porque sua intenção é expor os recursos, não detalhes do schema do seu banco de dados.
-
Novamente, apenas use substantivos quando nomeando a URL de um recurso e não tente explicar a funcionalidade.
Por que?
Apenas use substantivos nos recursos na URL, evite coisas como
/addNewUser
ou/updateUser
. Também, evite enviar operações sobre os recursos como parâmetros. -
Explicite as operações de CRUD usando funcionalidades do métodos HTTP:
Como:
GET
: Para obter/recuperar um recurso.POST
: Para criar um novo recurso ou sub-recurso.PUT
: Para atualizar recursos existentes.PATCH
: Para atualizar recursos existentes. Atualiza apenas os campos enviados deixando as outras propriedades como eram.DELETE
: Para deletar um recurso existente.
-
Para recursos aninhados, use a relação entre eles e a URL. Por exemplo, usando
id
para se referir a um usuário específico.Por que?
Esse é um jeito natural de tornar os recursos fáceis de explorar.
Como?
GET /schools/2/students
, Deve obter a lista de estudantes da escola com ID 2.GET /schools/2/students/31
, Deve obter os detalhes do estudante 31, que pertence a escola 2.DELETE /schools/2/students/31
, Deve deletar o estudante 31, que pertence a escola 2.PUT /schools/2/students/31
, Deve atualizar as informações do estudante 31, Use PUT apenas para URL de recursos, não para coleções.POST /schools
, Deve criar uma nova escola e retornar os detalhes da nova escola criada. Use POST em URL de coleções. -
Use um simples número ordinal para a versão com o prefixo
v
(v1, v2). Coloque a versão à esquerda de todos URL da api:http://api.domain.com/v1/schools/3/students
Por que?
Quando suas APIs são públicas, atualizar a API com alguma mudança que quebra o funcionamento antigo (Breaking Change) pode levar ao mal funcionamento de vários produtos e serviços que dependem da sua API. Usnado versões na URL você previne isso de acontecer. Leia mais sobre...
-
Messagens das respostas devem ser auto descritivas. Uma boa mensagem de erro deve ser algo parecido com:
{ "code": 1234, "message": "Algo de errado aconteceu", "description": "Mais detalhes" }
Ou para validação de erros:
{ "code": 2314, "message": "Validação Falhou", "errors": [ { "code": 1233, "field": "email", "message": "Email inválido" }, { "code": 1234, "field": "password", "message": "Senha em branco" } ] }
Por que?
Desenvolvedores dependem de erros bem descritivos em momentos críticos quando eles estão com dificuldades resolvendo problemas da aplicação que eles construíram usando sua API.
Nota: Mantenha mensagens relacionadas a exceções de segurança o mais genéricas possível. Por exemplo, ao invés de 'Senha incorreta', você pode responder dizendo 'Usuário ou senha inválidos' para que não vaze informações sobre dados corretos que não deveriam ser conhecido por terceiros.
-
Use códigos de status para enviar e descrever suas respostas ao invés de tudo funcionou corretamente, App do cliente fez algo errado ou A API fez algo errado.
Quais? >
200 OK
resposta de sucesso para requisiçõesGET
,PUT
ouPOST
.> `201 Created` para quando uma nova instância é criada. Criar uma nova instância usando `POST` deve retornar o código de status `201`. > `204 No Content` resposta representa sucesso porém não tem nenhum conteúdo para ser enviado na resposta. Use quando operações com `DELETE` são bem sucedidas. > `304 Not Modified` resposta para minimizar informações trafegadas quando o "requerente" já possui os dados em cache. > `400 Bad Request` para quando a requisição não foi processada, como por exemplo quando o servidor não compreendeu o conteúdo da requisição. > `401 Unauthorized` para quando a requisição não possui credenciais suficientes para ser executada. > `403 Forbidden` siginifica que o servidor entendeu a requisição mas se recusa a realizá-la. > `404 Not Found` indica que o recurso da requisição não foi encontrado. > `500 Internal Server Error` indica que a requisição foi recebida mas devida à algum erro interno a requisição não pode ser completada. _Por que?_ > A maioria das APIs fornecem um algum subconjunto de códigos de status HTTP. Por exemplo, a API do Google GData usa apenas 10 códigos, Netflix usa 9, e Digg, apenas 8. Evidente que essas requisições possuem dados com informações adicionais. Existem mais de 70 códigos de status HTTP. De qualquer forma, A maioria dos desenvolvedores não tem todos memorizados. Então se você escolher códigos que não são muito comuns pode assustar e repelir desenvolvedores de usar sua API. [Leia mais sobre...](https://apigee.com/about/blog/technology/restful-api-design-what-about-errors)
- Forneça o número total de recursos na sua resposta.
- Aceite
limit
eoffset
como parâmetros. - A quantidade de dados que os recursos expõem deve ser levado em consideração. O consumidor da API nem sempre precisa ter uma representação completa do recurso. Use
fields
na query string para filtrar propriedades a serem enviadas:GET /student?fields=id,name,age,class
- Paginação, filtragem e ordenação não precisam ser suportadas inicialmente para todos os recursos. Documente os recursos que oferecem tais funcionalidades.
Algumas boas práticas básicas de segurança:
-
Não use autenticação básica a não ser sob uma conexão HTTPS. Tokens de autenticação não devem ser enviados na URL:
GET /users/123?token=asdf....
Por que?
Porque tokens ou ID de usuário e senha são enviados pela rede como texto (encoded como base64, mas base64 é um encoding reversível), o esquema básico de autenticação não é seguro Leia mais sobre...
-
Tokens devem ser enviados fazendo uso do header
Authorization
em todas as requisições:Authorization: Bearer xxxxxx, Extra yyyyy
. -
Códigos de autorização devem ter "tempo de vida curto".
-
Rejeite qualquer requisição não-TLS não respondendo nenhuma requisição HTTP para evitar vazamento de dados. Apenas responda
403 Forbidden
. -
Considere usar Limite de requisições.
Por que?
Para proteger sua API de requisições maliciosas repetidas milhares de vezes por hora. Você deve considerar implementar Limite de requisições o mais cedo possível.
-
Configurando os headers HTTP corretamente pode te ajudar a protejer sua aplicação web. Leia mais sobre...
-
Sua API deve converter os dados recebidos para sua forma canônica ou rejeita-los. Retrone status
400 Bad Request
com detalhes sobre os de dados errados ou faltantes. -
Todos os dados trocados com a API REST devem ser validados pela API.
-
Serialize seu JSON.
Por que?
Uma das principais preocupações lidando com JSON encoders é previnir JavaScript malicioso de ser executado no browser... Ou, se você está usando
node.js
, no servidor. É vital usar JSON corretamente serializados para evitar a execução de código enviado como input pelo broswer. -
Valide o content-type e na maioria dos casos use
application/*json
(Content-Type header).Por que?
Por exemplo, aceitando
application/x-www-form-urlencoded
mime type permite que alguém com má intenções crie um form e execute uma simple requisição POST. O servidor nunca deve tentar adivinhar o Content-Type. A falta do Content-Type ou um Content-Type inesperado deve resultar no servidor recusando a request com um erro4XX
na resposta. -
Confira o checklist de segurança para um projeto de API. Leia mais sobre...
- Complete a seção
API Reference
no README.md Template para sua API. - Descreva os métodos de autenticação da sua API com exemplos de código.
- Explique a estrutura de recursos da sua URL (apenas o caminho do recurso) incluindo o tipo de request (Método).
Para cada endpoint
explique:
-
Parâmetros da URL se existirem, especifique de acordo com os nomes na descritos na seção de URL:
Required: id=[integer] Optional: photo_id=[alphanumeric]
-
Se o tipo da requisiçõa é POST, forneça alguns exemplos de código. Essa regra se aplica para parâmetros de URL também. Separe a seção entre
Requeridos
eOpcionais
. -
Resposta de sucesso, qual deveria ser o código de status e tem algum dado à ser retornado junto? Isso é útil quando as pessoas precisam saber o que os seus
callbacks
devem esperar:Code: 200 Content: { id : 12 }
-
Mensagens de erro, a maioria dos
endpoints
possuem várias maneiras de falhar. De acesso negado à parâmetros errados e etc. Todos devem ser listados. Pode parecer repetitivo, mas ajuda a previnir que desenvolvedores tentem prever o que vai acontecer. Por exemplo -
{ "code": 403, "message": "Authentication failed", "description": "Invalid username or password" }
- Use ferramentas de design de API, existem muitas ferramentas de código aberto para uma boa documentação como API Blueprint e Swagger.
Tenha certeza de usar recursos aos quais você possui o direito de uso. Se você usa bibliotecas, lembre-se de procurar por MIT, Apache ou BSD mas se você precisa modifica-las, então confira nos detalhes da licença. Imagens e vídeos com copyright podem te causar problemas.
Fontes: RisingStack Engineering, Mozilla Developer Network, Heroku Dev Center, Airbnb/javascript, Atlassian Git tutorials, Apigee, Wishtack
Icons by icons8