Skip to content

tech4works/gopen-gateway

Project status Playground Docker Go Report Card GitHub go.mod Go version of a Go module GoDoc FOSSA Status

United States Inglês | Spain Espanhol

O projeto GOPEN foi criado no intuito de ajudar os desenvolvedores a terem uma API Gateway robusta e de fácil manuseio, com a oportunidade de atuar em melhorias agregando a comunidade, e o mais importante, sem gastar nada. Foi desenvolvida, pois muitas APIs Gateway do mercado de forma gratuita, não atendem muitas necessidades mínimas para uma aplicação, induzindo-o a fazer o upgrade.

Com essa nova API Gateway você não precisará equilibrar pratos para economizar na sua infraestrutura e arquitetura, e ainda otimizará o seu desenvolvimento, veja abaixo todos os recursos disponíveis:

  • Json de configuração e ENVs simplificado para múltiplos ambientes.

  • Timeout granular, com uma configuração padrão, mas podendo especificar para cada endpoint.

  • Cache granular local ou global utilizando Redis, com estratégia e condição para o armazenamento customizável para cada endpoint.

  • Limitador de uso e de carga granular, com uma configuração padrão, mas podendo especificar para cada endpoint.

  • Segurança de CORS com validações de origens, método HTTP e headers.

  • Criação de templates de beforewares, backends, afterwares. Evitando duplicidade nas configurações e otimizando o uso nos endpoints.

  • Processamento de múltiplos tipos de backends por endpoint:

    • HTTP: Requisição direta a um serviço de API.
    • PUBLISHER: Publicação de mensagem em filas ou tópicos.
  • Processe de forma paralela todos os backends do seu endpoint caso configurado.

  • Aborte o processo de execução dos backends pelo código de status de forma personalizada.

  • Chamadas concorrentes ao backend HTTP caso configurado.

  • Propagação de mudança nas requisições futuras a partir de uma resposta do middleware (beforeware).

  • Customização completa de requisição e resposta para o seu backend:

    • HTTP
      • Omita informações.
      • Mapeamento. (Header, Query e Body)
      • Projeção. (Header, Query e Body)
      • Personalização da nomenclatura do body.
      • Personalização do tipo do conteúdo do body.
      • Comprima o body de requisição usando GZIP ou DEFLATE.
      • Modificadores, pontos e ações especificas para modificar algum conteúdo específico. (Header, Query, Param, Body)
      • Agrupe o body de resposta num campo específico informado.
    • PUBLISHER
      • Omita informações vazias. (Body)
      • Mapeamento. (Body)
      • Projeção. (Body)
      • Modificadores, pontos e ações especificas para modificar algum conteúdo. (Body)
      • Construa os atributos de mensagem a partir de informacoes de requisição e respostas.
  • Customização completa de resposta de endpoint:

    • Omita informações vazias do body.
    • Agregue múltiplas respostas dos backends.
    • Personalização do tipo do body.
    • Personalização da nomenclatura do body.
    • Comprima o body de requisição usando GZIP ou DEFLATE.
  • Rastreamento distribuído utilizando Elastic APM, Dashboard personalizado no Kibana, e logs bem estruturados com informações relevantes de configuração e acessos à API (exemplo).

📖 Documentação

⚙️ Configuração

Expandir conteúdo

⚠️ Variáveis de ambiente

Expandir conteúdo

Independente de como irá utilizar a API Gateway, ela exige duas variáveis de ambiente que são:

🚪 PORT

Porta aonde a sua API Gateway irá ouvir e servir.

Exemplo: 8080

📄 ENV

Qual ambiente sua API Gateway irá atuar (necessario apenas se estrutura de pastas tiverem referenciado seus ambientes).

Exemplo: dev

🗂️ Estrutura de pastas

Expandir conteúdo

Na estrutura do projeto, em sua raiz precisará ter uma pasta chamada "gopen" e dentro dela precisa ter as pastas contendo os nomes dos seus ambientes, você pode dar o nome que quiser, essa pasta precisará ter pelo menos o arquivo ".json" de configuração da API Gateway, ficará mais o menos assim, por exemplo:

nome-do-seu-projeto
| - docker-compose.yml
| - gopen
  | - dev
  |   - .json
  |   - .env // optional
  | - prd
  |   - .json

Outra opção que podemos trabalhar é inutilizar essas pastas por ambiente, funcionará de uma forma mais simples, exemplo:

nome-do-seu-projeto
| - docker-compose.yml
| - gopen
  | - .json
  | - .env // optional

🛠️ JSON

Com base nesse arquivo JSON de configuração obtido informada, a aplicação terá os seus endpoints e a suas regras definidas, veja abaixo todos os campos possíveis e os seus conceitos e regras:

👀 Exemplo

Expandir conteúdo

Abaixo adicionamos um JSON de exemplo com todas as possibilidades possíveis de configuração.

📚 Tipos customizados

Expandir conteúdo

Estes tipos são utilizados ao longo da configuração para padronizar valores aceitos.

🔹 duration
Expandir conteúdo

Representa um tempo no formato número/unidade.

Propriedade Valor
Tipo base string
Formato <number><unit>
Regex ^(?:\d+(?:\.\d+)?(?:h|m|s|ms|us|ns)
Unidade Descrição
ns nanossegundos
us microssegundos
ms milissegundos
s segundos
m minutos
h horas
{
  "timeout": "5s",
  "duration": "15m",
  "delay": "500ms"
}
🔹 byte-unit
Expandir conteúdo

Representa tamanho em bytes.

Propriedade Valor
Tipo base string
Formato <number><unit>
Regex ^\d+(B|KB|MB|GB|TB|PB|EB|ZB|YB)$
Unidade Descrição
B Bytes
KB Kilobytes
MB Megabytes
GB Gigabytes
TB Terabytes
PB Petabytes
EB Exabytes
ZB Zettabytes
YB Yottabytes
{
  "max-body-size": "10MB",
  "max-header-size": "8KB"
}
🔹 http-method
Expandir conteúdo

Métodos HTTP suportados.

Tipo base string
Valores aceitos
GET
POST
PUT
PATCH
DELETE
🔹 backend-kind
Expandir conteúdo

Define o tipo de backend executado.

Tipo base string
Valores aceitos Descrição
HTTP Realiza uma chamada HTTP/HTTPS para um serviço de API.
PUBLISHER Publica uma mensagem em tópicos ou filas.
🔹 backend-broker
Expandir conteúdo

Define o broker utilizado pelo backend.

Tipo base string
Valores aceitos Tipo de backend
AWS/SQS PUBLISHER
AWS/SNS PUBLISHER
🔹 content-type
Expandir conteúdo

Define o tipo de conteúdo utilizado na serialização.

Tipo base string
Valores aceitos
JSON
XML
PLAIN_TEXT
🔹 content-encoding
Expandir conteúdo

Define o tipo de compressão aplicado.

Tipo base string
Valores aceitos
NONE
GZIP
DEFLATE
🔹 nomenclature
Expandir conteúdo

Define o padrão de nomenclatura aplicado a campos JSON.

Tipo base string
Valores aceitos
LOWER_CAMEL
CAMEL
SNAKE
SCREAMING_SNAKE
KEBAB
SCREAMING_KEBAB
🔹 template-merge
Expandir conteúdo

Define como o template será combinado com a configuração local.

Tipo base string
Valores aceitos Descrição
BASE Mescla apenas os campos basicos como (id, dependencies, kind, hosts, provider, path, method)
FULL Mescla todos os campos.

🌎 Configuração Global

Expandir conteúdo

Campos na raiz do JSON de configuração.

Campo Tipo Obrigatório Padrão Descrição
$schema string URL do JSON Schema para validação.
@comment string Campo livre para anotações.
version string Usado para controle de versão e também usado no retorno do endpoint estático /version.
hot-reload boolean false Utilizado para o carregamento automático quando houver alguma alteração no arquivo .json e .env na pasta do ambiente selecionado.
proxy object Utilizado para configurar um proxy local para expor publicamente sua API Gateway localmente.
store object local Define a configuração do armazenamento global.
timeout duration 30s Responsável pelo tempo máximo de duração do processamento de cada requisição.
cache object Responsável pelas conf. globais de cache.
limiter object Responsável pelas regras de limitação, seja de tamanho ou taxa.
security-cors object Responsável pela segurança e política CORS.
templates object Responsável por instanciar as configurações de backends reutilizáveis.
endpoints array[object] Representa cada endpoint da API Gateway que será registrado para ouvir e servir as requisições HTTP.
🗄️ Store
Expandir conteúdo

Objeto de configuração global para armazenamento de cache.

Campo Tipo Obrigatório Padrão Descrição
redis object Configuração de armazenamento via Redis.
Campo Tipo Obrigatório Padrão Descrição
address string URL referente a conexão com Redis.
password string Senha para acesso a base Redis.
🗃️ Cache
Expandir conteúdo

Objeto de configuração global de cache.

Campo Tipo Obrigatório Padrão Descrição
enabled boolean ℹ️ false Indica se cache esta habilitado para o endpoint. (Apenas para o endpoint, e é obrigatório)
duration string Tempo de vida do cache.
strategy-headers array[string] Utilizado para adicionar uma estratégia para chave do cache a partir dos headers informados, complementando o padrão método:url.
only-if-methods array[string] ["GET"] Métodos HTTP aceitos.
only-if-status-codes array[int] 2xx Código de status aceitos.
allow-cache-control boolean false Considerar ou não o header Cache-Control vindo da requisição.
🚧 Limiter
Expandir conteúdo

Objeto de configuração global para limitar os recursos recebidos.

Campo Tipo Obrigatório Padrão Descrição
max-header-size string 1MB Responsável por limitar o tamanho do cabeçalho da requisição
max-body-size string 3MB Responsável por limitar o tamanho do corpo da requisição
max-multipart-memory-size string 5MB Responsável por limitar o tamanho do corpo multipart/form da requisição
rate.capacity int 5 Indica a capacidade máxima de requisições
rate.every string 1s Indica o valor da duração da verificação da capacidade máxima de requisições

⚠️ IMPORTANTE

Caso a requisição ultrapasse uma das regras, API Gateway irá abortar com os seguintes códigos de status:

  • max-header-size: 431 (Request header fields too large)
  • max-body-size ou max-multipart-memory-size: 413 (Request entity too large)
  • rate: 429 (Too many requests)
🔒 Security-Cors
Expandir conteúdo

Objeto de configuração global para de segurança CORS.

Campo Tipo Obrigatório Padrão Descrição
allow-origins array[string] Responsável por limitar o acesso apenas dos IPs de origem informados na lista
allow-methods array[string] Responsável por limitar o acesso apenas pelos métodos HTTP informados na lista
allow-headers array[string] Responsável por limitar o preenchimento de campos especificos do cabeçalho da requisição

⚠️ IMPORTANTE

Caso a requisição não seja permitida em uma das regras, API Gateway irá abortar com o código de status: 403 (Forbidden)

📝 Templates
Expandir conteúdo

Objeto utilizado para instanciar configurações de backends a partir do seu fluxo, evitando duplicação e melhor reutilização dos recursos.

Campo Tipo Descrição
beforewares object Instancia configurações de backends do fluxo beforeware. (middleware pré-backends).
backends object Instancia configurações de backends do fluxo principal.
afterwares object instancia configurações de backends do fluxo afterware. (middleware pós-backends).

📡 Endpoint

Expandir conteúdo

Objeto que representa o endpoint da API Gateway que será registrado para ouvir e servir as requisições HTTP.

Campo Tipo Obrigatório Padrão Descrição
@comment string Campo livre para anotações.
path string Responsável pelo caminho URI do endpoint que irá ouvir e servir.
method string Responsável por definir qual método HTTP o endpoint será registrado.
timeout string Config. Global Responsável pela configuração de timeout para o endpoint em questão.
cache object Config. Global Responsável pela configuração de cache para o endpoint em questão.
limiter object Config. Global Responsável pela configuração de limitação para o endpoint em questão.
security-cors object Config. Global Responsável pela configuração de security CORS para o endpoint em questão.
abort-if-status-codes array[int] >= 400 Indica quais codigos de status HTTP respondidos pelos backends pode ser abortado.
parallelism boolean false Indica que endpoint deverá executar todos os backends principais e afterwares de forma paralela (assíncrona).
beforewares array[object] Middlewares executados antes do fluxo principal.
backends array[object] Backends de fluxo principal.
afterwares array[object] Middlewares executados após o fluxo principal.
response object Responsável pela customização da resposta do endpoint.
📥 Endpoint Response
Expandir conteúdo

Objeto responsável pela customização do cabeçalho e corpo da resposta do endpoint. Veja mais sobre a modelagem de resposta da API Gateway clicando aqui.

Campo Tipo Obrigatório Padrão Descrição
@comment string Campo livre para anotações.
continue-on-error boolean false Indica que o endpoint deve continuar mesmo com erro na customização da resposta HTTP do endpoint.
header object Responsável pela customização do cabeçalho da resposta HTTP do endpoint.
body object Responsável pela customização do corpo da resposta HTTP do endpoint.
🧾 Endpoint Response Header
Expandir conteúdo

Objeto responsável pela customização do cabeçalho da resposta do endpoint.

Campo Tipo Obrigatório Padrão Descrição
@comment string Campo livre para anotações.
mapper object Responsável por mapear os campos do cabeçalho da resposta HTTP do endpoint, fazendo um de/para do nome do campo atual para o nome desejado.
projector object Responsável por projetar apenas os campos que deseja do cabeçalho da resposta HTTP do endpoint.
📦 Endpoint Response Body
Expandir conteúdo

Objeto responsável pela customização do corpo da resposta do endpoint.

Campo Tipo Obrigatório Padrão Descrição
@comment string Campo livre para anotações.
aggregate boolean false Agrega todas os corpos de respostas dos backends normais no mesmo corpo de resposta.
omit-empty boolean false Remove campos vazios (null,"",0, false) no corpo da resposta.
content-type string Tipo de conteúdo que deseja responder no corpo.
content-encoding string NONE Tipo de compressão que deseja responder no corpo.
nomenclature string Qual tipo de nomenclatura que deseja responder no corpo JSON/XML.
mapper object Responsável por mapear os campos do corpo da resposta, fazendo um de/para do nome do campo atual para o nome desejado.
projector object Responsável por projetar apenas os campos que deseja do corpo JSON da resposta.

🤖 Backend

Expandir conteúdo

Objeto que representa o backend do endpoint da API Gateway que será executado.

Campo Tipo Origem Tipo permitido Fluxo Obrigatório Padrão Descrição
@comment string Campo livre para anotações.
id string INLINE Identificador unico no endpoint do backend. Caso não informado, o campo path será usado como.
dependencies array[string] Indica que o mesmo depende de outros backends que precisam esta referenciado antes do mesmo na configuração do endpoint.
only-if array[string] Apenas executa o backend se pelo menos 1 indice informado retornar true.
ignore-if array[string] Ignora a execução do backend se pelo menos 1 indice informado retornar true.
template object INLINE Responsável por referenciar e herdar as informações configuradas no template.
kind string ℹ️ Indica qual o tipo de backend. (Apenas obrigatório se template não informado)
broker string PUBLISHER ℹ️ Indica qual o broker do backend. (Apenas obrigatório se tipo for PUBLISHER)
async boolean false Executa o backend de forma assíncrona. Ele anula o campo parallelism do endpoint caso informado.
hosts array[string] HTTP Indica os hosts para o caminho do backend a ser executado. (Veja mais sobre o balance clicando aqui)
path string Indica o caminho URI/URL do backend a ser executado.
method string HTTP Responsável por definir qual método HTTP backend será executado.
request object HTTP Responsável pela customização da requisição HTTP enviada ao backend.
response object HTTP PRINCIPAL Responsável pela customização da resposta final HTTP retornada do backend.
propagate object BEFOREWARE Responsável pela propagação das proximas requisições a partir da resposta do middleware beforeware retornada do backend.
group-id string PUBLISHER ℹ️ Indica qual o grupo de mensagem. (Apenas obrigatório se topico ou fila for do tipo FIFO e broker AWS)
deduplication-id string PUBLISHER ℹ️ Identificador usado para detectar mensagens duplicadas. (Apenas obrigatório se topico ou fila for do tipo FIFO e broker AWS)
delay string PUBLISHER 0s Publica a mensagem no tópico ou fila com atraso. (Verifique se o broker usado tem compatibilidade com entrega com atraso)
message object PUBLISHER Responsável pela customização do payload da mensagem a ser publicado no tópico ou fila.
📝 Backend Template
Expandir conteúdo

Objeto responsável por referenciar e herdar as informações configuradas no template.

Campo Tipo Obrigatório Padrão Descrição
path string Referência o caminho do template que precisa ser herdado.
merge string FULL Indica qual tipo de herança que quer herdar.

⚠️ IMPORTANTE

Só é permitido referênciar template no flow de configuração que está:

  • beforeware -> templates.beforewares
  • backend -> templates.backend
  • afterware -> templates.afterwares
📤 Backend Request
Expandir conteúdo

Objeto responsável pela customização da requisição HTTP enviada ao backend.

Campo Tipo Obrigatório Padrão Descrição
@comment string Campo livre para anotações.
continue-on-error boolean false Indica que o backend deve continuar mesmo com erro na customização da requisição.
concurrent int 1 Responsável pela quantidade de requisições HTTP concorrentes que deseja fazer ao serviço backend. (Min 2)
header object Responsável pela customização do cabeçalho da requisição HTTP enviada ao serviço backend.
param object Responsável pela customização dos parâmetros da URL de requisição HTTP enviada ao serviço backend.
query object Responsável pela customização dos parâmetros de busca da requisição HTTP enviada ao serviço backend.
body object Responsável pela customização do corpo da requisição HTTP enviada ao serviço backend.
🧾 Backend Request Header
Expandir conteúdo

Objeto responsável pela customização do cabeçalho da requisição HTTP enviada ao backend.

Campo Tipo Obrigatório Padrão Descrição
@comment string Campo livre para anotações.
omit boolean false Omita todas as informações do cabeçalho vindas da requisição do endpoint para o backend.
mapper object Responsável por mapear os campos do cabeçalho da requisição HTTP enviada ao serviço backend, fazendo um de/para do nome do campo atual para o nome desejado.
projector object Responsável por projetar apenas os campos que deseja do cabeçalho da requisição HTTP enviada ao serviço backend.
modifiers array[object] Responsável por modificações especificas do cabeçalho da requisição HTTP enviada ao serviço backend.
🔗 Backend Request Param
Expandir conteúdo

Objeto responsável pela customização dos parâmetros da URL de requisição HTTP enviada ao backend.

Campo Tipo Obrigatório Padrão Descrição
@comment string Campo livre para anotações.
modifiers array[object] Responsável por modificações especificas dos parâmetros da URL de requisição HTTP enviada ao serviço backend.
🔎 Backend Request Query
Expandir conteúdo

Objeto responsável pela customização dos parâmetros de busca da requisição HTTP enviada ao backend.

Campo Tipo Obrigatório Padrão Descrição
@comment string Campo livre para anotações.
omit boolean false Omita todas as informações de buscas vindas da requisição do endpoint para o backend.
mapper object Responsável por mapear os parâmetros de busca da requisição HTTP enviada ao serviço backend, fazendo um de/para do nome do campo atual para o nome desejado.
projector object Responsável por projetar apenas os parâmetros de busca que deseja da requisição HTTP enviada ao serviço backend.
modifiers array[object] Responsável por modificações especificas dos parâmetros de busca da requisição HTTP enviada ao serviço backend.
📦 Backend Request Body
Expandir conteúdo

Objeto responsável pela customização do corpo da resposta do endpoint.

Campo Tipo Obrigatório Padrão Descrição
@comment string Campo livre para anotações.
omit boolean false Omita todas as informações do corpo vindas da requisição HTTP do endpoint para o backend.
omit-empty boolean false Remove campos vazios (null,"",0, false) no corpo da requisição HTTP enviada ao serviço backend.
content-type string Tipo de conteúdo que deseja enviar no corpo da requisição HTTP enviada ao serviço backend.
content-encoding string NONE Tipo de compressão que deseja enviar no corpo da requisição HTTP enviada ao serviço backend.
nomenclature string Qual tipo de nomenclatura que deseja enviar no corpo JSON/XML da requisição HTTP enviada ao serviço backend.
mapper object Responsável por mapear os campos do corpo da requisição HTTP enviada ao serviço backend, fazendo um de/para do nome do campo atual para o nome desejado.
projector object Responsável por projetar apenas os campos que deseja do corpo JSON da requisição HTTP enviada ao serviço backend.
modifiers array[object] Responsável por modificações especificas dos campos do corpo da requisição HTTP enviada ao serviço backend.

endpoint.backends

Campo obrigatório, do tipo lista de objeto, responsável pela execução de serviços do endpoint.

endpoint.backend.@comment

Campo opcional, do tipo string, campo livre para anotações.

endpoint.backend.id

Campo opcional, do tipo string, campo livre para anotações.

endpoint.backend.hosts

Campo obrigatório, do tipo lista de string, é responsável pelos hosts do seu serviço que a API Gateway irá chamar com o campo backend.path.

De certa forma podemos ter um load balancer "burro", pois o backend irá sortear nessa lista qual host irá ser chamado, com isso podemos informar múltiplas vezes o mesmo host para balancear as chamadas, veja:

50% para cada host

[
  "https://instance-01",
  "https://instance-02"
]

75% no host "instance-01" e 15% no host "instance-02"

[
  "https://instance-01",
  "https://instance-02",
  "https://instance-02",
  "https://instance-02"
]

33.3% no host "instance-01" e 66.7% no host "instance-02"

[
  "https://instance-01",
  "https://instance-02",
  "https://instance-02"
]

endpoint.backend.path

Campo obrigatório, do tipo string, o valor indica a URL do caminho do serviço backend.

Utilizamos um dos endpoint.backend.hosts informados e juntamos com o path fornecido, por exemplo, no campo hosts temos o valor

[
  "https://instance-01",
  "https://instance-02"
]

E nesse campo path temos o valor

/users/status

O backend irá construir a seguinte URL de requisição depois do load balance

https://instance-02/users/status

Veja como o host é balanceado clicando aqui.

endpoint.backend.method

Campo obrigatório, do tipo string, o valor indica qual método HTTP o serviço backend espera.

endpoint.backend.request

Campo opcional, do tipo objeto, é responsável pela customização da requisição que será feita ao backend.

endpoint.backend.request.@comment

Campo opcional, do tipo string, campo livre para anotações.

endpoint.backend.request.concurrent

Campo opcional, do tipo inteiro, é responsável pela quantidade de requisições concorrentes que deseja fazer ao serviço backend.

O valor padrão é 0, indicando que será executado apenas 1 requisição de forma síncrona, os valores aceitos são de no mínimo 2 e no máximo 10.

endpoint.backend.request.omit-header

Campo opcional, do tipo booleano, o valor padrão é false, indica o desejo de omitir o cabeçalho da requisição.

endpoint.backend.request.omit-query

Campo opcional, do tipo booleano, o valor padrão é false, indica o desejo de omitir todos os parâmetros de busca da requisição.

endpoint.backend.request.omit-body

Campo opcional, do tipo booleano, o valor padrão é false, indica o desejo de omitir o corpo da requisição.

endpoint.backend.request.content-type

Campo opcional, do tipo string, é responsável por informar qual conteúdo deseja para o corpo da requisição.

Valores aceitos

  • JSON
  • XML
  • TEXT

Exemplo

Corpo de requisição atual:

{
  "id": "Summer",
  "name": "Veranito fresquito"
}

Configuramos o campo content-type para XML e o resultado foi:

<root>
    <id>Summer</id>
    <name>Veranito fresquito</name>
</root>

endpoint.backend.request.content-encoding

Campo opcional, do tipo string, é responsável por informar qual codificação deseja para o corpo da requisição.

Valores aceitos

  • NONE (Remove a codificação caso tenha, e retorna sem nenhum tipo de codificação)
  • GZIP
  • DEFLATE

endpoint.backend.request.nomenclature

Campo opcional, do tipo string, é responsável por informar qual nomenclatura deseja para os campos do corpo JSON da requisição.

Valores aceitos

  • LOWER_CAMEL
  • CAMEL
  • SNAKE
  • SCREAMING_SNAKE
  • KEBAB
  • SCREAMING_KEBAB

Exemplo

Corpo atual:

{
  "id": "Summer",
  "name": "Veranito fresquito",
  "start_date": "2017/02/10",
  "end_date": "2017/02/15",
  "address": {
    "street_address": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postal_code": "10021"
  }
}

Configuramos o campo nomenclature para LOWER_CAMEL e o resultado foi:

{
  "id": "Summer",
  "name": "Veranito fresquito",
  "startDate": "2017/02/10",
  "endDate": "2017/02/15",
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postalCode": "10021"
  }
}

endpoint.backend.request.omit-empty

Campo opcional, do tipo booleano, o valor padrão é false, indica o desejo de omitir os campos vazios do corpo JSON da requisição.

endpoint.backend.request.header-mapper

Campo opcional, é responsável por mapear os campos do cabeçalho de requisição, fazendo um de/para do nome do campo atual para o nome desejado, veja o exemplo:

Cabeçalho atual:

Content-Type: application/json
X-Value-Id: 4ae6c92d16089e521626
X-Device-Id: asajlaks212
X-Test-Id: asdkmalsd123
Date: Tue, 23 Apr 2024 11:37:26 GMT
Content-Length: 620

Configuração do header-mapper:

{
  "X-Value-Id": "X-New-Value-Id",
  "X-Device-Id": "X-New-Device-Id",
  "X-Test-Id": "X-New-Test-Id"
}

Resultado

Content-Type: application/json
X-New-Value-Id: 4ae6c92d16089e521626
X-New-Device-Id: asajlaks212
X-New-Test-Id: asdkmalsd123
Date: Tue, 23 Apr 2024 11:37:26 GMT
Content-Length: 620

⚠️ IMPORTANTE

Só é permitido a customização de chaves não obrigatórias que não sejam:

  • Content-Type
  • Content-Encoding
  • Content-Length
  • X-Forwarded-For

endpoint.backend.request.query-mapper

Campo opcional, do mapa chave-valor string, é responsável por mapear os campos dos parâmetros de busca da requisição, fazendo um de/para do nome do campo atual para o nome desejado, veja o exemplo:

URL com os parâmetros de busca:

/users?id=23&email=gabrielcataldo@gmail.com&phone=47991271234

Configuração query-mapper:

{
  "id": "user_id",
  "email": "mail",
  "phone": "phone_number"
}

Resultado:

/users?user_id=23&mail=gabrielcataldo@gmail.com&phone_number=47991271234

endpoint.backend.request.body-mapper

Campo opcional, do tipo mapa chave-valor string, é responsável por mapear os campos do corpo JSON da requisição, fazendo um de/para do nome do campo atual para o nome desejado, veja o exemplo:

Corpo atual da requisição:

{
  "id": 1,
  "firstName": "John",
  "lastName": "Smith",
  "age": 25,
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postalCode": "10021"
  }
}

Configuração do body-mapper:

{
  "firstName": "personalData.firstName",
  "lastName": "personalData.lastName",
  "age": "personalData.age"
}

Resultado:

{
  "id": 1,
  "personalData": {
    "firstName": "John",
    "lastName": "Smith",
    "age": 25
  },
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postalCode": "10021"
  }
}

endpoint.backend.request.header-projection

Campo opcional, do tipo objeto, é responsável por customizar o envio de campos do cabeçalho de requisição ao serviço backend.

Valores aceitos para os campos

  • -1: Significa que você deseja remover o campo indicado.
  • 1: Significa que você deseja manter o campo indicado.

Exemplo

Cabeçalho atual:

Content-Type: application/json
X-Value-Id: 4ae6c92d16089e521626
X-Device-Id: asajlaks212
X-Test-Id: asdkmalsd
X-User-Id: 123
Date: Tue, 23 Apr 2024 11:37:26 GMT
Content-Length: 620

Configuração do header-projection:

{
  "X-Value-Id": 1,
  "X-User-Id": 1
}

Resultado:

Content-Type: application/json
X-Value-Id: 4ae6c92d16089e521626
X-User-Id: 123
Date: Tue, 23 Apr 2024 11:37:26 GMT
Content-Length: 620

⚠️ IMPORTANTE

Só é permitido a customização de chaves não obrigatórias que não sejam:

  • Content-Type
  • Content-Encoding
  • Content-Length
  • X-Forwarded-For

endpoint.backend.request.query-projection

Campo opcional, do tipo objeto, é responsável por customizar o envio dos parâmetros de busca da requisição ao serviço backend.

Valores aceitos para os campos

  • -1: Significa que você deseja remover o campo indicado.
  • 1: Significa que você deseja manter o campo indicado.

Exemplo

URL:

/users?id=23&email=gabrielcataldo@gmail.com&phone=47991271234

Configuração do query-projection:

{
  "id": -1
}

Resultado:

/users?email=gabrielcataldo@gmail.com&phone=47991271234

endpoint.backend.request.body-projection

Campo opcional, do tipo objeto, é responsável por customizar o envio dos campos do corpo JSON da requisição ao serviço backend.

Valores aceitos para os campos

  • -1: Significa que você deseja remover o campo indicado.
  • 1: Significa que você deseja manter o campo indicado.

Exemplo

Corpo atual:

{
  "id": 1,
  "firstName": "John",
  "lastName": "Smith",
  "age": 25,
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postalCode": "10021"
  }
}

Configuração do body-projection:

{
  "age": -1,
  "address.postalCode": -1
}

Resultado:

{
  "id": 1,
  "firstName": "John",
  "lastName": "Smith",
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY"
  }
}

endpoint.backend.request.header-modifiers

Campo opcional, do tipo lista de objeto, valor padrão é vazio, é responsável por modificações especificas do cabeçalho da requisição ao serviço backend.

endpoint.backend.request.header-modifier.@comment

Campo opcional, do tipo string, campo livre para anotações.

endpoint.backend.request.header-modifier.action

Campo obrigatório, do tipo string, responsável pela ação a ser tomada na modificação do cabeçalho.

Valores aceitos

  • ADD: Adiciona a chave informada no campo header.key caso não exista, e agrega o valor informado no campo header.value.

  • APD: Acrescenta o valor informado no campo header.value caso a chave informada no campo header.key exista.

  • SET: Define o valor da chave informada no campo header.key pelo valor passado no campo header.value.

  • RPL: Substitui o valor da chave informada no campo header.key pelo valor passado no campo header.value caso exista.

  • DEL: Remove a chave informada no campo header.key caso exista.

endpoint.backend.request.header-modifier.key

Campo obrigatório, do tipo string, utilizado para indicar qual chave do cabeçalho deve ser modificada.

endpoint.backend.request.header-modifier.value

Campo obrigatório, do tipo string, utilizado como valor a ser usado para modificar a chave indicada no campo header.key.

Temos possibilidades de utilização de valores dinâmicos, e de variáveis de ambiente para esse campo.

⚠️ IMPORTANTE

Se torna opcional apenas se header.action tiver o valor DEL.

endpoint.backend.request.header-modifier.propagate

Campo opcional, do tipo booleano, o valor padrão é false indicando que o modificador não deve propagar essa mudança em questão para os backends seguintes.

Caso informado como true essa modificação será propagada para os seguintes backends.

endpoint.backend.request.param-modifiers

Campo opcional, do tipo lista de objeto, valor padrão é vazio, é responsável por modificações especificas dos parâmetros da URL da requisição ao serviço backend.

endpoint.backend.request.param-modifier.@comment

Campo opcional, do tipo string, campo livre para anotações.

endpoint.backend.request.param-modifier.action

Campo obrigatório, do tipo string, responsável pela ação a ser tomada na modificação dos parâmetros da URL da requisição.

Valores aceitos

  • SET: Define o valor da chave informada no campo param.key pelo valor passado no campo param.value.

  • RPL: Substitui o valor da chave informada no campo param.key pelo valor passado no campo param.value caso exista.

  • DEL: Remove a chave informada no campo param.key caso exista.

endpoint.backend.request.param-modifier.key

Campo obrigatório, do tipo string, utilizado para indicar qual chave de parâmetro da URL deve ser modificada.

endpoint.backend.request.param-modifier.value

Campo obrigatório, do tipo string, utilizado como valor a ser usado para modificar a chave indicada no campo param.key.

Temos possibilidades de utilização de valores dinâmicos, e de variáveis de ambiente para esse campo.

⚠️ IMPORTANTE

Se torna opcional apenas se param.action tiver o valor DEL.

endpoint.backend.request.param-modifier.propagate

Campo opcional, do tipo booleano, o valor padrão é false indicando que o modificador não deve propagar essa mudança em questão para os backends seguintes.

Caso informado como true essa modificação será propagada para os seguintes backends.

endpoint.backend.request.query-modifiers

Campo opcional, do tipo lista de objeto, valor padrão é vazio, responsável pelas modificações de parâmetros de busca da requisição ao serviço backend.

endpoint.backend.request.query-modifier.@comment

Campo opcional, do tipo string, campo livre para anotações.

endpoint.backend.request.query-modifier.action

Campo obrigatório, do tipo string, responsável pela ação a ser tomada na modificação dos parâmetros de busca da requisição.

Valores aceitos

  • ADD: Adiciona a chave informada no campo query.key caso não exista, e agrega o valor informado no campo query.value.

  • APD: Acrescenta o valor informado no campo query.value caso a chave informada no campo query.key exista.

  • SET: Define o valor da chave informada no campo query.key pelo valor passado no campo query.value.

  • RPL: Substitui o valor da chave informada no campo query.key pelo valor passado no campo query.value caso exista.

  • DEL: Remove a chave informada no campo query.key caso exista.

endpoint.backend.request.query-modifier.key

Campo obrigatório, do tipo string, utilizado para indicar qual chave de parâmetro de busca deve ser modificada.

endpoint.backend.request.query-modifier.value

Campo obrigatório, do tipo string, utilizado como valor a ser usado para modificar a chave indicada no campo query.key.

Temos possibilidades de utilização de valores dinâmicos, e de variáveis de ambiente para esse campo.

⚠️ IMPORTANTE

Se torna opcional apenas se query.action tiver o valor DEL.

endpoint.backend.request.query-modifier.propagate

Campo opcional, do tipo booleano, o valor padrão é false indicando que o modificador não deve propagar essa mudança em questão para os backends seguintes.

Caso informado como true essa modificação será propagada para os seguintes backends.

endpoint.backend.request.body-modifiers

Campo opcional, do tipo lista de objeto, valor padrão é vazio, responsável pelas modificações do corpo da requisição ao serviço backend.

endpoint.backend.request.body-modifier.@comment

Campo opcional, do tipo string, campo livre para anotações.

endpoint.backend.request.body-modifier.action

Campo obrigatório, do tipo string, responsável pela ação a ser tomada na modificação do corpo da requisição.

Valores aceitos se o corpo for do tipo JSON

  • ADD: Adiciona a chave informada no campo body.key caso não exista, e agrega o valor informado no campo body.value.

  • APD: Acrescenta o valor informado no campo body.value caso a chave informada no campo body.key exista.

  • SET: Defini o valor da chave informada no campo body.key pelo valor passado no campo body.value.

  • RPL: Substitui o valor da chave informada no campo body.key pelo valor passado no campo body.value caso exista.

  • REN: Renomeia a chave informada no campo body.key pelo valor passado no campo body.value caso exista.

  • DEL: Remove a chave informada no campo body.key caso exista.

Valores aceitos se o corpo for TEXTO

  • ADD: Agrega o valor informado no campo body.value ao texto.

  • APD: Acrescenta o valor informado no campo body.value caso body não for vazio.

  • RPL: Irá substituir todos os valores semelhantes à chave informada no campo body.key pelo valor passado no campo body.value.

  • DEL: Remove todos os valores semelhantes à chave informada no campo body.key.

endpoint.backend.request.body-modifier.key

Campo obrigatório, do tipo string, utilizado para indicar qual chave do corpo da requisição deve ser modificada.

⚠️ IMPORTANTE

Se torna opcional se seu body for do tipo TEXTO e body.action tiver o valor ADD.

endpoint.backend.request.body-modifier.value

Campo obrigatório, do tipo string, utilizado como valor a ser usado para modificar a chave indicada no campo body.key.

Temos possibilidades de utilização de valores dinâmicos, e de variáveis de ambiente para esse campo.

⚠️ IMPORTANTE

Se torna opcional apenas se body.action tiver o valor DEL.

endpoint.backend.request.body-modifier.propagate

Campo opcional, do tipo booleano, o valor padrão é false indicando que o modificador não deve propagar essa mudança em questão para os backends seguintes.

Caso informado como true essa modificação será propagada para os seguintes backends.

endpoint.backend.response

Campo opcional, do tipo objeto, é responsável pela customização da resposta recebida pelo serviço backend.

endpoint.backend.response.@comment

Campo opcional, do tipo string, campo livre para anotações.

endpoint.backend.response.omit

Campo opcional, do tipo booleano, o valor padrão é false, indica o desejo de omitir toda a resposta ao usuário final HTTP.

endpoint.backend.response.omit-header

Campo opcional, do tipo booleano, o valor padrão é false, indica o desejo de omitir o cabeçalho da resposta.

endpoint.backend.response.omit-body

Campo opcional, do tipo booleano, o valor padrão é false, indica o desejo de omitir o corpo da resposta.

endpoint.backend.response.group

Campo opcional, do tipo string, é responsável por agregar todo o corpo da resposta em um campo JSON, veja no exemplo abaixo:

Corpo atual:

[
  "test",
  "value",
  "array"
]

Configuração do campo group com o valor test_list que resultou:

{
  "test_list": [
    "test",
    "value",
    "array"
  ]
}

endpoint.backend.response.header-mapper

Campo opcional, é responsável por mapear os campos do cabeçalho de resposta, fazendo um de/para do nome do campo atual para o nome desejado, veja o exemplo:

Cabeçalho atual:

Content-Type: application/json
X-Value-Id: 4ae6c92d16089e521626
X-Device-Id: asajlaks212
X-Test-Id: asdkmalsd123
Date: Tue, 23 Apr 2024 11:37:26 GMT
Content-Length: 620

Configuração do header-mapper:

{
  "X-Value-Id": "X-New-Value-Id",
  "X-Device-Id": "X-New-Device-Id",
  "X-Test-Id": "X-New-Test-Id"
}

Resultado:

Content-Type: application/json
X-New-Value-Id: 4ae6c92d16089e521626
X-New-Device-Id: asajlaks212
X-New-Test-Id: asdkmalsd123
Date: Tue, 23 Apr 2024 11:37:26 GMT
Content-Length: 620

⚠️ IMPORTANTE

Só é permitido a customização de chaves não obrigatórias que não sejam:

  • Content-Type
  • Content-Encoding
  • Content-Length

endpoint.backend.response.body-mapper

Campo opcional, do tipo mapa chave-valor string, é responsável por mapear os campos do corpo JSON da resposta, fazendo um de/para do nome do campo atual para o nome desejado, veja o exemplo:

Corpo atual da resposta:

{
  "id": 1,
  "firstName": "John",
  "lastName": "Smith",
  "age": 25,
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postalCode": "10021"
  }
}

Configuração do body-mapper:

{
  "firstName": "personalData.firstName",
  "lastName": "personalData.lastName",
  "age": "personalData.age"
}

Resultado:

{
  "id": 1,
  "personalData": {
    "firstName": "John",
    "lastName": "Smith",
    "age": 25
  },
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postalCode": "10021"
  }
}

endpoint.backend.response.header-projection

Campo opcional, do tipo objeto, é responsável por customizar o envio de campos do cabeçalho de resposta do serviço backend.

Valores aceitos para os campos

  • -1: Significa que você deseja remover o campo indicado.
  • 1: Significa que você deseja manter o campo indicado.

Exemplo

Cabeçalho atual:

Content-Type: application/json
X-Value-Id: 4ae6c92d16089e521626
X-Device-Id: asajlaks212
X-Test-Id: asdkmalsd
X-User-Id: 123
Date: Tue, 23 Apr 2024 11:37:26 GMT
Content-Length: 620

Configuração do header-projection:

{
  "X-Value-Id": 1,
  "X-User-Id": 1
}

Resultado:

Content-Type: application/json
X-Value-Id: 4ae6c92d16089e521626
X-User-Id: 123
Date: Tue, 23 Apr 2024 11:37:26 GMT
Content-Length: 620

⚠️ IMPORTANTE

Só é permitido a customização de chaves não obrigatórias que não sejam:

  • Content-Type
  • Content-Encoding
  • Content-Length

endpoint.backend.response.body-projection

Campo opcional, do tipo objeto, é responsável por customizar o envio dos campos do corpo JSON da resposta do serviço backend.

Valores aceitos para os campos

  • -1: Significa que você deseja remover o campo indicado.
  • 1: Significa que você deseja manter o campo indicado.

Exemplo

Corpo atual:

{
  "id": 1,
  "firstName": "John",
  "lastName": "Smith",
  "age": 25,
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postalCode": "10021"
  }
}

Configuração do body-projection:

{
  "age": -1,
  "address.postalCode": -1
}

Resultado:

{
  "id": 1,
  "firstName": "John",
  "lastName": "Smith",
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY"
  }
}

endpoint.backend.response.header-modifiers

Campo opcional, do tipo lista de objeto, valor padrão é vazio, é responsável por modificações especificas do cabeçalho de resposta do serviço backend.

endpoint.backend.response.header-modifier.@comment

Campo opcional, do tipo string, campo livre para anotações.

endpoint.backend.response.header-modifier.action

Campo obrigatório, do tipo string, responsável pela ação a ser tomada na modificação do cabeçalho da resposta.

Valores aceitos

  • ADD: Adiciona a chave informada no campo header.key caso não exista, e agrega o valor informado no campo header.value.

  • APD: Acrescenta o valor informado no campo header.value caso a chave informada no campo header.key exista.

  • SET: Define o valor da chave informada no campo header.key pelo valor passado no campo header.value.

  • RPL: Substitui o valor da chave informada no campo header.key pelo valor passado no campo header.value caso exista.

  • DEL: Remove a chave informada no campo header.key caso exista.

endpoint.backend.response.header-modifier.key

Campo obrigatório, do tipo string, utilizado para indicar qual chave do cabeçalho deve ser modificada.

endpoint.backend.response.header-modifier.value

Campo obrigatório, do tipo string, utilizado como valor a ser usado para modificar a chave indicada no campo header.key.

Temos possibilidades de utilização de valores dinâmicos, e de variáveis de ambiente para esse campo.

⚠️ IMPORTANTE

Se torna opcional apenas se header.action tiver o valor DEL.

endpoint.backend.response.body-modifiers

Campo opcional, do tipo lista de objeto, valor padrão é vazio, responsável pelas modificações do corpo da resposta do serviço backend.

endpoint.backend.response.body-modifier.@comment

Campo opcional, do tipo string, campo livre para anotações.

endpoint.backend.response.body-modifier.action

Campo obrigatório, do tipo string, responsável pela ação a ser tomada na modificação do corpo da resposta.

Valores aceitos se o corpo for do tipo JSON

  • ADD: Adiciona a chave informada no campo body.key caso não exista, e agrega o valor informado no campo body.value.

  • APD: Acrescenta o valor informado no campo body.value caso a chave informada no campo body.key exista.

  • SET: Defini o valor da chave informada no campo body.key pelo valor passado no campo body.value.

  • RPL: Substitui o valor da chave informada no campo body.key pelo valor passado no campo body.value caso exista.

  • REN: Renomeia a chave informada no campo body.key pelo valor passado no campo body.value caso exista.

  • DEL: Remove a chave informada no campo body.key caso exista.

Valores aceitos se o corpo for TEXTO

  • ADD: Agrega o valor informado no campo body.value ao texto.

  • APD: Acrescenta o valor informado no campo body.value caso body não for vazio.

  • RPL: Irá substituir todos os valores semelhantes à chave informada no campo body.key pelo valor passado no campo body.value.

  • DEL: Remove todos os valores semelhantes à chave informada no campo body.key.

endpoint.backend.response.body-modifier.key

Campo obrigatório, do tipo string, utilizado para indicar qual chave do corpo da requisição deve ser modificada.

⚠️ IMPORTANTE

Se torna opcional se seu body for do tipo TEXTO e body.action tiver o valor ADD.

endpoint.backend.response.body-modifier.value

Campo obrigatório, do tipo string, utilizado como valor a ser usado para modificar a chave indicada no campo body.key.

Temos possibilidades de utilização de valores dinâmicos, e de variáveis de ambiente para esse campo.

⚠️ IMPORTANTE

Se torna opcional apenas se body.action tiver o valor DEL.

endpoint.response

Campo opcional, do tipo objeto, é responsável pela customização da resposta do endpoint.

Veja mais sobre as regras de resposta da API Gateway clicando aqui.

endpoint.response.@comment

Campo opcional, do tipo string, livre para anotações.

endpoint.response.body

Campo opcional, do tipo objeto, é responsável pela customização do corpo da resposta do endpoint,

endpoint.response.body.aggregate

Campo opcional, do tipo booleano, o valor padrão é false, é responsável por agregar todos os corpos das respostas recebidas pelos backends em apenas um corpo.

endpoint.response.body.content-type

Campo opcional, do tipo string, é responsável por informar qual conteúdo deseja para o corpo de resposta do endpoint.

Valores aceitos

  • JSON
  • XML
  • TEXT

endpoint.response.body.content-encoding

Campo opcional, do tipo string, é responsável por informar qual codificação deseja para o corpo da resposta do endpoint.

Valores aceitos

  • NONE (Remove a codificação caso tenha, e retorna sem nenhum tipo de codificação)
  • GZIP
  • DEFLATE

endpoint.response.body.nomenclature

Campo opcional, do tipo string, é responsável por informar qual nomenclatura deseja para os campos do corpo JSON da resposta do endpoint.

Valores aceitos

  • LOWER_CAMEL
  • CAMEL
  • SNAKE
  • SCREAMING_SNAKE
  • KEBAB
  • SCREAMING_KEBAB

endpoint.response.body.omit-empty

Campo opcional, do tipo booleano, o valor padrão é false, indica o desejo de omitir os campos vazios do corpo JSON da resposta do endpoint.

JSON de tempo de execução

O Gopen API Gateway quando iniciado, gera um arquivo JSON, baseado no JSON de configuração, localizado na pasta runtime na raiz da sua aréa de trabalho.

Esse JSON, indica qual foi o entendimento da aplicação ao ler o JSON de configuração, todas as #variáveis de configuração já terão seus valores substituídos, caso exista.

Esse json também pode ser lido utilizando a rota estática /settings.

Rotas estáticas

O Gopen API Gateway tem alguns endpoints estáticos, isto é, indepêndente de qualquer configuração feita, teremos atualmente três endpoints cadastrados nas rotas do mesmo, veja abaixo cada um e suas responsabilidades:

ping

Endpoint para saber se a API Gateway está viva o path, retorna 404 (Not found) se tiver off, e 200 (OK) se tiver no ar.

version

Endpoint que retorna a versão obtida na config version, retorna 404 (Not Found) se não tiver sido informado no json de configuração, caso contrário retorna o 200 (OK) com o valor no body como texto.

settings

Endpoint retorna algumas informações sobre o projeto, como versão, data da versão, quantidade de contribuintes e um resumo de quantos endpoints, middlewares, backends e modifiers configurados no momento e o json de configuração que está rodando ativamente.

{
  "version": "v1.0.0",
  "version-date": "03/27/2024",
  "founder": "Gabriel Cataldo",
  "contributors": 1,
  "endpoints": 4,
  "middlewares": 1,
  "backends": 7,
  "setting": {}
}

Variáveis de ambiente

As variáveis de ambiente podem ser fácilmente instânciadas utilizando o arquivo .env, na pasta indicada pelo ambiente dinâmico de inicialização como mencionado no tópico ESTRUTURA DE PASTAS.

Caso preferir inserir os valores utilizando docker-compose também funcionará corretamente, ponto é que a API Gateway irá ler o valor gravado na máquina, independente de como foi inserido nela.

Os valores podem ser utilizados na configuração do JSON da API Gateway, basta utilizar a sintaxe $NOME como um valor string, veja no exemplo abaixo.

Um trecho de um JSON de configuração, temo os seguintes valores:

{
  "version": "$VERSION",
  "hot-reload": true,
  "store": {
    "redis": {
      "address": "$REDIS_URL",
      "password": "$REDIS_PASSWORD"
    }
  },
  "timeout": "$TIMEOUT"
}

E na nossa máquina temos as seguintes variáveis de ambiente:

VERSION=1.0.0

REDIS_URL=redis-18885.c259.us-east-1-4.ec2.cloud.redislabs.com:18985
REDIS_PASSWORD=12345

TIMEOUT=5m

A API Gateway gera um arquivo de JSON de tempo de execução ao rodar a aplicação, veja o resultado do mesmo após iniciar a aplicação:

{
  "version": "1.0.0",
  "hot-reload": true,
  "store": {
    "redis": {
      "address": "redis-18885.c259.us-east-1-4.ec2.cloud.redislabs.com:18985",
      "password": "12345"
    }
  },
  "timeout": "5m"
}

Vimos que todos os valores com a sintaxe $NOME foram substituídos pelos seus devidos valores, caso um valor tenha sido mencionado por essa sintaxe, porém não existe nas variáveis de ambiente, o mesmo valor informado será mantido.

Valores dinâmicos para modificação

Podemos utilizar valores de requisição e resposta do tempo de execução do endpoint, conforme o mesmo foi configurado. Esses valores podem ser obtidos por uma sintaxe específica, temos as seguintes possibilidades de obtenção desses valores, veja:

Requisição

Quando menciona a sintaxe #request... você estará obtendo os valores da requisição recebida.

#request.header...

Esse trecho da sintaxe irá obter do cabeçalho da requisição o valor indicado, por exemplo, #request.header.X-Forwarded-For.0 irá obter o primeiro valor do campo X-Forwarded-For do cabeçalho da requisição caso exista, substituindo a sintaxe pelo valor, o resultado foi 127.0.0.1.

#request.params...

Esse trecho da sintaxe irá obter dos parâmetros da requisição o valor indicado, por exemplo, #request.params.id irá obter o valor do campo id dos parâmetros da requisição caso exista, substituindo a sintaxe pelo valor, o resultado foi 72761.

#request.query...

Esse trecho da sintaxe irá obter dos parâmetros de busca da requisição o valor indicado, por exemplo, #request.query.email.0 irá obter o primeiro valor do campo email dos parâmetros de busca da requisição caso exista, substituindo a sintaxe pelo valor, o resultado foi gabrielcataldo.adm@gmail.com.

#request.body...

Esse trecho da sintaxe irá obter do body da requisição o valor indicado, por exemplo, #request.body.deviceId irá obter o valor do campo deviceId do body da requisição caso exista, substituindo a sintaxe pelo valor, o resultado foi 991238.

Resposta

Quando menciona a sintaxe #responses... você estará obtendo os valores do histórico de respostas dos backends do endpoint sendo beforewares, backends e afterwares

No exemplo, eu tenho apenas um backend e o mesmo foi processado, então posso está utilizando a sintaxe:

#responses.0.header.X-Value.0

Nesse outro exemplo de sintaxe temos três backends configurados e dois já foram processados, então podemos utilizar a seguinte sintaxe no processo do terceiro backend:

#responses.1.body.users.0

Nesses exemplos citados vemos que podemos obter o valor da resposta de um backend que já foi processado, e que estão armazenados em um tipo de histórico temporário.

Importante

Você pode utilizar com base nesses campos, a sintaxe de JSON path que se enquadra em seus valores, apenas se lembre que, os objetos header, query são mapas de lista de string, e o params é um mapa de string.

Aprenda na prática como utilizar os valores dinâmicos para modificação usando o projeto playground que já vem com alguns exemplos de modificadores com valores dinâmicos.

Lógica de resposta

Quando utilizamos uma API Gateway nos perguntamos, como será retornado ao meu cliente a resposta desse endpoint configurado?

Para facilitar o entendimento criamos esse tópico para resumir a lógica de resposta da nossa API Gateway, então vamos começar.

Como funciona?

A API Gateway foi desenvolvida com uma inteligência e flexibilidade ao responder um endpoint, ela se baseia em dois pontos importantes, primeiro, na quantidade de respostas de serviços backends que foram processados, e segundo, nos campos de customização da resposta configurados nos objetos endpoint e backend. Vamos ver alguns exemplos abaixo para melhor entendimento.

Único backend

Nesse exemplo trabalharemos apenas com um único backend, veja como a API Gateway se comportará ao responder a esse cenário:

Json de configuração

{
  "$schema": "https://raw.githubusercontent.com/tech4works/gopen-gateway/main/json-schema.json",
  "endpoints": [
    {
      "path": "/users/find/:key",
      "method": "GET",
      "backends": [
        {
          "hosts": [
            "$USER_SERVICE_URL"
          ],
          "path": "/users/find/:key",
          "method": "GET"
        }
      ]
    }
  ]
}

Ao processar esse endpoint a resposta da API Gateway foi:

HTTP/1.1 200 OK

Cabeçalho (Veja sobre os cabeçalhos de resposta aqui)

Content-Type: application/json
X-Gopen-Cache: false
X-Gopen-Complete: true
X-Gopen-Success: true
Date: Tue, 23 Apr 2024 11:37:26 GMT
Content-Length: 620

Corpo

{
  "id": "6499b8826493f85e45eb3794",
  "name": "Gabriel Cataldo",
  "birthDate": "1999-01-21T00:00:00Z",
  "gender": "MALE",
  "currentPage": "HomePage",
  "createdAt": "2023-06-26T16:10:42.265Z",
  "updatedAt": "2024-03-10T20:19:03.452Z"
}

Vimos que no exemplo a API Gateway serviu como um proxy redirecionando a requisição para o serviço backend configurado e espelhando seu body de resposta, e agregando seus valores no cabeçalho de resposta.

Nesse mesmo exemplo vamos forçar um cenário de infelicidade na resposta do backend, veja:

HTTP/1.1 404 Not Found

Cabeçalho (Veja sobre os cabeçalhos de resposta aqui)

Content-Type: application/json
X-Gopen-Cache: false
X-Gopen-Complete: true
X-Gopen-Success: false
Date: Tue, 23 Apr 2024 21:56:33 GMT
Content-Length: 235

Corpo

{
  "file": "datastore/user.go",
  "line": 227,
  "endpoint": "/users/find/gabrielcataldo.adma@gmail.com",
  "message": "user not found"
}

Neste caso a API Gateway também espelhou a resposta da única chamada de backend do endpoint.

Utilizando middlewares

Nesse exemplo, vamos utilizar os middlewares de beforewares e afterwares, como esses backends são omitidos ao cliente final se tiverem sucesso, vamos simular uma chamada com o device bloqueado para que o beforeware retorne um erro, e depois um afterware que responderá também um erro, pois não existe, vamos lá!

Json de configuração

{
  "$schema": "https://raw.githubusercontent.com/tech4works/gopen-gateway/main/json-schema.json",
  "middlewares": {
    "save-device": {
      "hosts": [
        "$DEVICE_SERVICE_URL"
      ],
      "path": "/devices",
      "method": "PUT"
    },
    "increment-attempts": {
      "hosts": [
        "$SECURITY_SERVICE_URL"
      ],
      "path": "/attempts",
      "method": "POST"
    }
  },
  "endpoints": [
    {
      "path": "/users/find/:key",
      "method": "GET",
      "beforewares": [
        "save-device"
      ],
      "afterwares": [
        "increment-attempts"
      ],
      "backends": [
        {
          "hosts": [
            "$USER_SERVICE_URL"
          ],
          "path": "/users/find/:key",
          "method": "GET"
        }
      ]
    }
  ]
}

Ao processar esse endpoint de exemplo simulando o erro na chamada de beforeware a resposta da API Gateway foi:

HTTP/1.1 403 Forbidden

Cabeçalho (Veja sobre os cabeçalhos de resposta aqui)

Content-Type: application/json
X-Gopen-Cache: false
X-Gopen-Complete: false
X-Gopen-Success: true
Date: Tue, 23 Apr 2024 23:02:09 GMT
Content-Length: 154

Corpo

{
  "file": "service/device.go",
  "line": 49,
  "endpoint": "/devices",
  "message": "unprocessed entity: device already exists and is not active"
}

Vimos que a resposta foi o espelho do retorno do beforeware save-device, pois como o mesmo retornou falha 403 (Forbidden), o endpoint abortou, não chamando os backends seguintes, lembrando que você pode configurar os códigos de status HTTP que vão ser abortados pelo seu endpoint, basta preencher o campo endpoint.abort-if-status-codes.

No seguinte exemplo iremos forçar um erro no afterware increment-attempts a da API Gateway resposta foi:

HTTP/1.1 404 Not Found

Cabeçalho (Veja sobre os cabeçalhos de resposta aqui)

Content-Type: text/plain
X-Gopen-Cache: false
X-Gopen-Complete: true
X-Gopen-Success: false
Date: Tue, 23 Apr 2024 23:16:57 GMT
Content-Length: 18

Corpo

404 page not found

Vimos que a resposta também foi o espelho do retorno do afterware increment-attempts, por mais que seja a última chamada de um serviço backend do endpoint, pois caiu na regra de resposta abortada, então, todas as outras respostas dos outros backends foram ignoradas e apenas foi retornado a resposta do backend abortado.

Veja mais sobre a resposta abortada.

Múltiplos backends

Nesse exemplo iremos trabalhar com três backends principais no endpoint, então, vamos lá!

Json de configuração

{
  "$schema": "https://raw.githubusercontent.com/tech4works/gopen-gateway/main/json-schema.json",
  "port": 8080,
  "endpoints": [
    {
      "path": "/users/find/:key",
      "method": "GET",
      "backends": [
        {
          "hosts": [
            "$USER_SERVICE_URL"
          ],
          "path": "/users/find/:key",
          "method": "GET"
        },
        {
          "hosts": [
            "$DEVICE_SERVICE_URL"
          ],
          "path": "/devices",
          "method": "PUT"
        },
        {
          "hosts": [
            "$USER_SERVICE_URL"
          ],
          "path": "/version",
          "method": "GET",
          "response": {
            "group": "version"
          }
        }
      ]
    }
  ]
}

No exemplo iremos executar os três backend com sucesso, a API Gateway respondeu

HTTP/1.1 200 OK

Cabeçalho (Veja sobre os cabeçalhos de resposta aqui)

Content-Type: application/json
X-Gopen-Cache: false
X-Gopen-Complete: true
X-Gopen-Success: true
Date: Tue, 23 Apr 2024 23:49:12 GMT
Content-Length: 755

Corpo

[
  {
    "ok": true,
    "code": 200,
    "id": "6499b8826493f85e45eb3794",
    "name": "Gabriel Cataldo",
    "birthDate": "1999-01-21T00:00:00Z",
    "gender": "MALE",
    "currentPage": "HomePage",
    "createdAt": "2023-06-26T16:10:42.265Z",
    "updatedAt": "2024-03-10T20:19:03.452Z"
  },
  {
    "ok": true,
    "code": 200,
    "id": "661535275d6fc736d831c754",
    "usersId": [
      "6499b8826493f85e45eb3793"
    ],
    "status": "ACTIVE",
    "createdAt": "2024-04-09T12:31:35.907Z",
    "updatedAt": "2024-04-23T23:49:12.759Z"
  },
  {
    "ok": true,
    "code": 200,
    "version": "v1.0.0"
  }
]

Temos alguns pontos nesse exemplo que vale ressaltar, primeiro com o formato, a API Gateway entendeu que seu endpoint tem múltiplas respostas e não foi utilizado o campo endpoint.response.aggregate com o valor true, então ela lista as respostas como JSON acrescentando os seguintes campos:

ok: Indica se a resposta do backend em questão teve o código de status HTTP entre 200 e 299.

code: É preenchido com código de status HTTP respondido pelo seu backend.

Esses campos são apenas acrescentado se houver múltiplas respostas e o campo endpoint.response.aggregate não for informado com o valor true.

Segundo ponto a destacar é no trecho "version": "v1.0.0" do último backend, o mesmo respondeu apenas um texto no body de resposta que foi v1.0.0, porém para esse cenário como foi mencionado, a API Gateway força a conversão desse valor para um JSON, adicionando um novo campo com o valor informado na configuração endpoint.backend.response.group do mesmo.

Terceiro ponto é sobre o código de status HTTP, o mesmo é retornado pela maior frequência, isto é, se temos três retornos 200 OK como no exemplo a API Gateway também retornará esse código. Se tivermos um retorno igualitário o último código de status HTTP retornado será considerado, veja os cenários possíveis dessa lógica:

[
  {
    "ok": true,
    "code": 204
  },
  {
    "ok": true,
    "code": 200
  },
  {
    "ok": true,
    "code": 201
  }
]

a API Gateway responderá 201 Created.

[
  {
    "ok": true,
    "code": 100
  },
  {
    "ok": true,
    "code": 100
  },
  {
    "ok": true,
    "code": 201
  }
]

a API Gateway responderá 100 Continue.

Quarto ponto a ser destacado, é que como o endpoint tem múltiplas respostas, consequentemente temos múltiplos cabeçalhos de resposta, a API Gateway irá agregar todos os campos e valores para o cabeçalho da resposta final, veja mais sobre o comportamento do cabeçalho de resposta clicando aqui.

Último ponto a ser destacado, é que caso um desses retornos de backend entre no cenário em que o endpoint aborta a resposta, ele não seguirá nenhuma diretriz mostrada no tópico em questão e sim lógica de resposta abortada.

Múltiplos backends agregados

Nesse exemplo iremos utilizar uma configuração parecida com JSON de configuração do exemplo acima, porém com campo endpoint.response.aggregate com o valor true.

Json de configuração

{
  "$schema": "https://raw.githubusercontent.com/tech4works/gopen-gateway/main/json-schema.json",
  "endpoints": [
    {
      "path": "/users/find/:key",
      "method": "GET",
      "response": {
        "aggregate": true
      },
      "backends": [
        {
          "hosts": [
            "$USER_SERVICE_URL"
          ],
          "path": "/users/find/:key",
          "method": "GET"
        },
        {
          "hosts": [
            "$DEVICE_SERVICE_URL"
          ],
          "path": "/devices",
          "method": "PUT"
        },
        {
          "hosts": [
            "$USER_SERVICE_URL"
          ],
          "path": "/version",
          "method": "GET",
          "response": {
            "group": "version"
          }
        }
      ]
    }
  ]
}

Ao processarmos o endpoint a resposta da API Gateway foi:

HTTP/1.1 200 OK

Cabeçalho (Veja sobre os cabeçalhos de resposta aqui)

Content-Type: application/json
X-Gopen-Cache: false
X-Gopen-Complete: true
X-Gopen-Success: true
Date: Wed, 24 Apr 2024 10:57:31 GMT
Content-Length: 665

Corpo

{
  "id": [
    "6499b8826493f85e45eb3794",
    "661535275d6fc736d831c754"
  ],
  "name": "Gabriel Cataldo",
  "gender": "MALE",
  "currentPage": "HomePage",
  "lastSeenAt": "2024-02-19T11:43:27.324Z",
  "createdAt": [
    "2024-04-09T12:31:35.907Z",
    "2023-06-26T16:10:42.265Z"
  ],
  "updatedAt": [
    "2024-04-24T11:04:32.184Z",
    "2024-03-10T20:19:03.452Z"
  ],
  "usersId": [
    "6499b8826493f85e45eb3793"
  ],
  "status": "ACTIVE",
  "version": "v1.0.0"
}

Vimos a única diferença de resposta do tópico Múltiplos backends é que ele agregou os valores de todas as respostas em um só JSON, e os campos que se repetiram foram agregados os valores em lista.

As demais regras como código de status HTTP, a conversão forçada para JSON, entre outras, seguem as mesmas regras mencionadas no tópico Múltiplos backends.

No exemplo podemos deixar a resposta agregada um pouco mais organizada, com isso vamos alterar o trecho do nosso segundo backend adicionando o campo endpoint.backend.response.group com o valor device, veja o trecho do JSON de configuração modificado:

{
  "hosts": [
    "$DEVICE_SERVICE_URL"
  ],
  "path": "/devices",
  "method": "PUT",
  "response": {
    "group": "device"
  }
}

Ao processar novamente o endpoint obtivemos a seguinte resposta:

HTTP/1.1 200 OK

Cabeçalho (Veja sobre os cabeçalhos de resposta aqui)

Content-Type: application/json
X-Gopen-Cache: false
X-Gopen-Complete: true
X-Gopen-Success: true
Date: Wed, 24 Apr 2024 11:23:07 GMT
Content-Length: 697

Corpo

{
  "id": "6499b8826493f85e45eb3793",
  "name": "Gabriel Cataldo",
  "birthDate": "1999-01-21T00:00:00Z",
  "gender": "MALE",
  "currentPage": "HomePage",
  "lastSeenAt": "2024-02-19T11:43:27.324Z",
  "createdAt": "2023-06-26T16:10:42.265Z",
  "updatedAt": "2024-03-10T20:19:03.452Z",
  "device": {
    "id": "661535275d6fc736d831c754",
    "usersId": [
      "6499b8826493f85e45eb3793"
    ],
    "status": "ACTIVE",
    "createdAt": "2024-04-09T12:31:35.907Z",
    "updatedAt": "2024-04-24T11:23:07.832Z"
  },
  "version": "v1.0.0"
}

Com essa configuração vimos que nossa resposta agregada ficou mais organizada, e como é importante entender sobre o json de configuração e seus campos, para que o GOPEN API Gateway atenda melhor suas necessidades.

Resposta abortada

Para uma resposta ser abortada pela API Gateway, um dos backends configurados do endpoint tanto middlewares como os principais, ao serem processados, na sua resposta, o código de status HTTP precisa seguir valores no campo endpoint.abort-if-status-codes do próprio endpoint.

IMPORTANTE

Ao abortar a resposta do backend, a API Gateway irá espelhar apenas a resposta do mesmo, código de status, cabeçalho e corpo, sendo assim, as outras respostas já processadas serão ignoradas.

Indicamos utilizar essa configuração apenas quando algo fugiu do esperado, como, por exemplo, uma resposta 500 (Internal server error).

Cabeçalho de resposta

Na resposta, a API Gateway com exceção dos campos Content-Length, Content-Type e Date agrega todos valores de cabeçalho respondidos pelos backends configurados no endpoint, indepêndente da quantidade de backends.

Campos de cabeçalho padrão

Também são adicionados até quatro campos no cabeçalho veja abaixo sobre os mesmos:

  • X-Gopen-Timeout: Enviado na requisição ao backend, ele contém o tempo restante para o processamento em milissegundos, com o mesmo dá para implementar um contexto com timeout linear nos seus microserviços, evitando vazamento de processos, já que após esse tempo a API Gateway retornara 504 (Gateway Timeout).

  • X-Gopen-Cache: Caso a resposta do endpoint não seja "fresca", isto é, foi utilizado a resposta armazenada em cache, é retornado o valor true, caso contrário retorna o valor false.

  • X-Gopen-Cache-Ttl: Caso a resposta do endpoint tenha sido feita utilizando o armazenamento em cache, ele retorna a duração do tempo de vida restante desse cache, caso contrário o campo não é retornado.

  • X-Gopen-Complete: Caso todos os backends tenham sido processados pelo endpoint é retornado o valor true, caso contrário é retornado o valor false.

  • X-Gopen-Success: Caso todos os backends tenham retornado sucesso, isto é, o código de status HTTP de resposta entre 200 a 299, ele retorna o valor true, caso contrário o valor false.

Lembrando que se a resposta de um backend for abortada, apenas o header do mesmo é agregado e considerado as regras dos campos acima.

Agora vamos ver alguns exemplos de cabeçalho de retorno:

Campos únicos de cabeçalho

Cabeçalho de resposta do backend 1:

Content-Type: application/json
X-Value-Id: 4ae6c92d16089e521626
X-MS: api-user
Date: Wed, 24 Apr 2024 11:23:07 GMT
Content-Length: 102

Cabeçalho de resposta do endpoint

Content-Type: application/json
X-Value-Id: 4ae6c92d16089e521626
X-MS: api-user
X-Gopen-Cache: false
X-Gopen-Complete: true
X-Gopen-Success: true
Date: Wed, 24 Apr 2024 11:23:08 GMT
Content-Length: 102

Vimos que no exemplo foram adicionados os campos padrões, e agregado os valores do cabeçalho de resposta, que foram X-Value-Id e X-MS.

Campos duplicados de cabeçalho

Cabeçalho de resposta do backend 1:

Content-Type: application/json
X-Value-Id: 4ae6c92d16089e521626
X-MS: api-user
Date: Wed, 24 Apr 2024 11:23:07 GMT
Content-Length: 102

Cabeçalho de resposta do backend 2:

Content-Type: application/json
X-Value-Id: 4ae6c92d16089e521638
X-MS: api-device
X-MS-Success: true
Date: Wed, 24 Apr 2024 11:23:08 GMT
Content-Length: 402

Cabeçalho de resposta do endpoint

Content-Type: application/json
X-Value-Id: 4ae6c92d16089e521626, 4ae6c92d16089e521638
X-MS: api-user, api-device
X-MS-Success: true
X-Gopen-Cache: false
X-Gopen-Complete: true
X-Gopen-Success: true
Date: Wed, 24 Apr 2024 11:23:09 GMT
Content-Length: 504

Vimos que no exemplo também foram adicionados os campos padrões, e agregado os valores do cabeçalho de resposta, que foram X-Value-Id, X-MS e X-MS-Success, vale ressaltar que os campos que se repetiram foram agrupados e separados por vírgula.

Respostas padrões

Toda API Gateway tem suas respostas padrão para cada cenário de erro, então iremos listar abaixo cada cenário e sua respectiva resposta HTTP:

204 (No Content)

Esse cenário acontece quando todos os backends forem preenchidos com a configuração endpoint.backend.response.omit como true e o endpoint foi processado corretamente, porém não há nada a ser retornado.

413 (Request Entity Too Large)

Esse cenário acontece quando o tamanho do corpo de requisição é maior do que o permitido para o endpoint, utilizando a configuração limiter.max-body-size para corpo normal e limiter.max-multipart-memory-size para envio do tipo form-data. Você pode customizar essa configuração para um endpoint específico utilizando o campo endpoint.limiter.

Cabeçalho

Content-Type: application/json
X-Gopen-Cache: false
X-Gopen-Complete: false
X-Gopen-Success: false
Date: Fri, 26 Apr 2024 11:56:06 GMT
Content-Length: 170

Corpo

{
  "file": "infra/size_limiter.go",
  "line": 92,
  "endpoint": "/users",
  "message": "payload too large error: permitted limit is 1.0B",
  "timestamp": "2024-04-26T08:56:06.628636-03:00"
}

429 (Too many requests)

Esse cenário acontece quando o limite de requisições são atingidas por um determinado IP, esse limite é definido na configuração limiter.rate. Você pode customizar essa configuração para um endpoint específico utilizando o campo endpoint.limiter.

Cabeçalho

Content-Type: application/json
X-Gopen-Cache: false
X-Gopen-Complete: false
X-Gopen-Success: false
Date: Fri, 26 Apr 2024 12:12:53 GMT
Content-Length: 177

Corpo

{
  "file": "infra/rate_limiter.go",
  "line": 100,
  "endpoint": "/users",
  "message": "too many requests error: permitted limit is 1 every 1s",
  "timestamp": "2024-04-26T09:12:53.501804-03:00"
}

431 (Request Header Fields Too Large)

Esse cenário acontece quando o tamanho do header é maior do que o permitido para o endpoint, utilizando a configuração limiter.max-header-size. Você pode customizar essa configuração para um endpoint específico utilizando o campo endpoint.limiter.

Cabeçalho

Content-Type: application/json
X-Gopen-Cache: false
X-Gopen-Complete: false
X-Gopen-Success: false
Date: Fri, 26 Apr 2024 11:39:53 GMT
Content-Length: 186

Corpo

{
  "file": "infra/size_limiter.go",
  "line": 80,
  "endpoint": "/multiple/backends/:key",
  "message": "header too large error: permitted limit is 1.0B",
  "timestamp": "2024-04-26T08:39:53.944055-03:00"
}

500 (Internal server error)

Esse cenário é específico quando algum erro inesperado ocorreu com a API Gateway, caso isso aconteça relate o problema aqui mostrando a resposta e o log impresso no terminal de execução.

Cabeçalho

Content-Type: application/json
X-Gopen-Cache: false
X-Gopen-Complete: false
X-Gopen-Success: false
Date: Fri, 26 Apr 2024 12:38:16 GMT
Content-Length: 183

Corpo

{
  "file": "middleware/panic_recovery.go",
  "line": 27,
  "endpoint": "/users",
  "message": "gateway panic error occurred! detail: runtime error: invalid memory address or nil pointer dereference",
  "timestamp": "2024-04-26T09:42:23.938997-03:00"
}

502 (Bad Gateway)

Esse cenário acontece quando ao tentar se comunicar com o backend, e ocorre alguma falha de comunicação com o mesmo.

Cabeçalho

Content-Type: application/json
X-Gopen-Cache: false
X-Gopen-Complete: false
X-Gopen-Success: false
Date: Thu, 25 Apr 2024 01:07:36 GMT
Content-Length: 277

Corpo

{
  "file": "infra/rest.go",
  "line": 69,
  "endpoint": "/users/find/:key",
  "message": "bad gateway error: Get \"http://192.168.1.8:8090/users/find/gabrielcataldo.adm@gmail.com\": dial tcp 192.168.1.8:8090: connect: connection refused",
  "timestamp": "2024-04-24T22:07:36.558851-03:00"
}

504 (Gateway Timeout)

Esse cenário acontece quando o endpoint excede o limite do tempo configurado no campo timeout. Você pode customizar essa configuração para um endpoint específico utilizando o campo endpoint.timeout.

Cabeçalho

Content-Type: application/json
X-Gopen-Cache: false
X-Gopen-Complete: false
X-Gopen-Success: false
Date: Fri, 26 Apr 2024 13:29:55 GMT
Content-Length: 150

Corpo

{
  "file": "middleware/timeout.go",
  "line": 81,
  "endpoint": "/users/version",
  "message": "gateway timeout: 5m",
  "timestamp": "2024-04-26T10:29:55.908526-03:00"
}

Observabilidade

O Gopen API Gateway tem por padrão uma integração com Elastic, podendo utilizar alguns serviços veja:

Dashboard

Discover

Stream Logs

APM Services

APM Trace

Vale destacar que preservamos e enviamos o trace para os serviços backend subjacentes utilizando o Elastic APM Trace, e sempre adicionamos o campo X-Forwarded-For com o IP do client.

Usabilidade

  • Playground um repositório para começar a explorar e aprender na prática!

  • Base um repositório para começar o seu novo projeto, apenas com o necessário!

Como contríbuir?

Ficamos felizes quando vemos a comunidade se apoiar, e projetos como esse, está de braços abertos para receber suas ideias, veja abaixo como participar.

Download

Para conseguir rodar o projeto primeiro faça o download da linguagem Go versão 1.22 ou superior na sua máquina.

Com o Go instalado na sua máquina, faça o pull do projeto

git pull https://github.com/tech4works/gopen-gateway.git

Depois abra o mesmo usando o próprio terminal com a IDE de sua preferência

Goland:

goland gopen-gateway

VSCode:

code gopen-gateway

Gitflow

Para inicializar o desenvolvimento, você pode criar uma branch a partir da main, para um futuro PR para a mesma.

Agradecimentos

Esse projeto teve apoio de bibliotecas fantásticas, esse trecho dedico a cada uma listada abaixa:

Obrigado por contribuir para a comunidade Go e facilitar o desenvolvimento desse projeto.

Licença Apache 2.0

FOSSA Status