Referência de configuração YAML

Esta página é escrita à mão, narrativa e organizada por caso de uso — comece por aqui. Uma referência gerada a partir do schema também está disponível (../articles/reference/schema.md), exaustiva e sempre em dia com o código, útil para conferir o vocabulário completo de um objeto de uma vez. As duas convivem de propósito, não são a mesma coisa reescrita duas vezes.

Esta página documenta, campo a campo, todo o vocabulário de um documento pipevine.dev/v1. Para uma introdução guiada com exemplos, veja o guia; para o catálogo de steps (o que cada type: dentro de um pipeline aceita), veja a referência de steps, gerada a partir do código.

Documento raiz

apiVersion: pipevine.dev/v1
kind: Application
metadata: { ... }
spec: { ... }
Campo Tipo Obrigatório Descrição
apiVersion string sim Identifica a versão do vocabulário YAML. Sempre pipevine.dev/v1 hoje — veja Versionamento
kind string sim Sempre Application
metadata objeto sim Identificação da aplicação — ver seção abaixo
spec objeto sim Onde o comportamento da aplicação é declarado — ver seções abaixo

metadata

Campo Tipo Obrigatório Descrição
name string sim Identificador da aplicação
version string sim Versão da aplicação (não confundir com apiVersion, a versão do vocabulário)
description string não Descrição livre da aplicação

spec.type

Campo Tipo Obrigatório Descrição
type api | consumer sim api expõe rotas HTTP (spec.routes); consumer consome mensagens de um broker (spec.consumers). Os dois compartilham exatamente o mesmo modelo de pipeline

spec.routes (para spec.type: api)

routes:
  - id: createOrder
    method: POST
    path: /orders/{orderId}
    summary: Cria um pedido
    tags: [orders]
    request: { ... }
    authorize: { ... }
    transaction: required
    cache: { ... }
    pipeline: [ ... ]
    response: { ... }
    errors: [ ... ]
Campo Tipo Obrigatório Descrição
id string sim Identificador da rota dentro da aplicação
method GET | POST | PUT | PATCH | DELETE | HEAD | OPTIONS sim Verbo HTTP
path string sim Caminho da rota, com parâmetros entre chaves ({orderId}), disponíveis em input.route
summary string não Alimenta a documentação OpenAPI gerada
tags lista de string não Alimenta a documentação OpenAPI gerada
request objeto não O que a rota aceita — ver seção request abaixo
auth objeto ({ scheme, ref }) não Sobrescreve spec.auth.default só para esta rota
anonymous boolean não Dispensa autenticação nesta rota especificamente
authorize objeto não Regras de autorização — ver seção authorize abaixo
transaction none | required não required abre uma transação de banco em volta de todo o pipeline da rota — necessário para mais de uma escrita atômica, ou para publish com mode: outbox
cache objeto não Cache-aside da resposta inteira — ver seção cache abaixo
pipeline lista de step não A sequência de steps executada para esta rota — ver referência de steps
response objeto não Como montar a resposta HTTP — ver seção response abaixo
errors lista de objeto não Mapeamento de código de erro → resposta HTTP — ver seção errors abaixo

request

Campo Tipo Obrigatório Descrição
body.schema string (nome de uma entrada de spec.schemas) não Não é um caminho de arquivo — é o name de um schema declarado em spec.schemas; referenciar um nome não declarado falha o build. Alimenta a documentação OpenAPI gerada — a validação de corpo em runtime continua sendo responsabilidade do step validate, explicitamente no pipeline
body.contentType string não Content type esperado do corpo
headers[].name string sim Nome do header
headers[].required boolean não Quando true, a ausência do header já responde 400 automaticamente, antes do pipeline rodar
headers[].description string não Alimenta a documentação OpenAPI gerada
query[].name string sim Nome do parâmetro de query
query[].type string não Tipo do parâmetro (string, boolean, integer, ...)
query[].required boolean não Quando true, a ausência do parâmetro já responde 400 automaticamente
query[].default — não Valor usado quando o parâmetro não é informado e não é obrigatório

authorize

Campo Tipo Obrigatório Descrição
scopes lista de string não Escopos exigidos do token/identidade autenticada
roles lista de string não Papéis exigidos
claims mapa string → string não Claims específicas exigidas, por nome e valor
expr expressão JSONata não Política de autorização livre, avaliada sobre o estado do pipeline (tipicamente input.claims)

cache (bloco da rota)

Campo Tipo Obrigatório Descrição
key expressão JSONata sim Chave de cache da resposta inteira
ttl duração (ex.: 5m) não Tempo de vida absoluto da entrada
tags lista de string não Tags para invalidação em grupo via cache.invalidate
bypassWhen expressão JSONata não Quando verdadeira, ignora o cache para aquela requisição específica

response

Campo Tipo Obrigatório Descrição
status integer não Status HTTP da resposta de sucesso
headers mapa string → expressão não Headers da resposta, cada valor avaliado como expressão JSONata
body expressão JSONata não Corpo da resposta
schema string (nome de uma entrada de spec.schemas) não Não é um caminho de arquivo — é o name de um schema declarado em spec.schemas. Serve à documentação OpenAPI gerada

errors

Campo Tipo Obrigatório Descrição
code string sim Código de erro produzido em algum ponto do pipeline. Além dos que você mesmo define com fail, quase todo step embutido emite um código próprio ao falhar (db_persist_failed, http_call_failed, validation_failed, ...)
status integer na prática, sim Status HTTP na resposta ProblemDetails. Ver o aviso abaixo: omitir não herda o status da falha
title string não Título legível na resposta ProblemDetails

Omitir status: força 500. Quando uma entrada de errors: casa com o código da falha, o status dela é usado sempre — e, se você não declarou status:, ele já vale 500. O status que o próprio step produziu é descartado nesse caso. Uma entrada como { code: CUSTOMER_NOT_FOUND, title: "Cliente não encontrado" } combinada com um fail ... status: 404 responde 500, não 404. Declare status: em toda entrada de errors:, ou não declare a entrada.

spec.consumers (para spec.type: consumer)

Os steps disponíveis dentro de pipeline são exatamente os mesmos do tipo api.

consumers:
  - id: onOrderPaid
    source: rabbit-main
    queue: orders.paid
    concurrency: 4
    prefetch: 20
    retry: { ... }
    deadLetter: { queue: orders.paid.dlq }
    idempotency: { ... }
    pipeline: [ ... ]
Campo Tipo Obrigatório Descrição
id string sim Identificador do consumidor
source string sim Referência a um item de spec.brokers
queue string não Fila a consumir (RabbitMQ)
topic string não Tópico a consumir (Kafka)
consumerGroup string não Grupo de consumidores (Kafka)
concurrency integer não Número de mensagens processadas em paralelo
prefetch integer não Quantidade de mensagens pré-buscadas do broker
retry.attempts integer não Número de tentativas antes de considerar a mensagem uma falha definitiva
retry.backoff.initial duração não Espera antes da primeira nova tentativa
retry.backoff.max duração não Teto do backoff exponencial
retry.backoff.jitter boolean não Adiciona variação aleatória ao backoff, para evitar tentativas sincronizadas
retry.on lista de integer não Não se aplica a um consumidor — o campo existe porque a mesma estrutura de retry é compartilhada com spec.integrations, onde filtra por status HTTP. Num consumidor, toda falha é retentada; declarar on: aqui não tem efeito
deadLetter.queue string sim (dentro de deadLetter) Fila para onde a mensagem vai depois de esgotar as tentativas
idempotency.key expressão JSONata sim (dentro de idempotency) Identifica a mensagem de forma única — precisa ser única por consumidor, não só por entidade de negócio
idempotency.store string não Referência a onde a chave de idempotência é registrada
idempotency.ttl duração não Por quanto tempo a chave é lembrada
pipeline lista de step não A sequência de steps executada para cada mensagem — ver referência de steps

spec.auth

auth:
  default: { scheme: jwt, ref: corp-idp }
  schemes:
    - { id: corp-idp, scheme: jwt, authority: "${config:Idp:Authority}", audience: orders-api }
Campo Tipo Obrigatório Descrição
default.scheme / default.ref string sim (dentro de default) Esquema aplicado a toda rota que não declara auth:/anonymous: true explicitamente
schemes[].id string sim Identificador do esquema, referenciado por ref em auth/default/authorize
schemes[].scheme string sim Qual implementação: jwt, oidc, mtls, basic, ou uma chave de terceiro

Os campos específicos de cada esquema (authority, signingKey, caCertificatePath, users, e os demais) estão detalhados em Autenticação e autorização, com um exemplo completo de cada um dos quatro esquemas embutidos.

spec.dataSources e spec.entities

dataSources:
  - { id: postgres-main, provider: postgres, connectionString: "${config:ConnectionStrings:Main}" }

entities:
  - name: Order
    table: orders
    dataSource: postgres-main
    key: id
    properties:
      - { name: id,         type: uuid }
      - { name: customerId, type: uuid,   index: true }
      - { name: total,      type: decimal, precision: 18, scale: 2 }
      - { name: items,      type: jsonb }
      - { name: createdAt,  type: timestamptz }
Campo Tipo Obrigatório Descrição
dataSources[].id string sim Identificador da fonte de dados, referenciado por entities[].dataSource
dataSources[].provider string sim Qual implementação: postgres, mysql, sqlite (os três relacionais do core) ou uma chave de terceiro
dataSources[].connectionString string depende do provider String de conexão, tipicamente via ${config:...}/${env:...}
entities[].name string sim Nome da entidade, referenciado pelos steps db.*
entities[].table string sim Tabela/coleção de armazenamento
entities[].dataSource string sim Referência a um item de dataSources
entities[].key string sim Campo usado como chave primária pelos steps db.find/db.update/db.delete
entities[].properties[].name string sim Nome do campo
entities[].properties[].type string sim Um de: uuid, string, int/integer, long, decimal, bool/boolean, datetime, timestamptz, jsonb/json
entities[].properties[].precision / .scale integer não Só para type: decimal
entities[].properties[].index boolean não Cria um índice nesse campo no bootstrap de tabela
entities[].options objeto livre depende do provider Configuração específica do provider de dados. O core não valida seus campos — quem valida é o provider, no build, nomeando a entidade e o campo desconhecido. É aqui que vivem partitionKey/clusteringKeys (Cassandra), partitionKey/sortKey/indexes (DynamoDB) e allowFiltering/allowScan. Ver Bancos NoSQL

Conversão de tipos por provider relacional

Todo token de type: acima é aceito pelos três providers relacionais (postgres/mysql/sqlite), mas nem todos são nativos nos três — onde não são, o provider converte, e a conversão pode perder informação:

type: postgres mysql sqlite
uuid uuid nativo char(36) TEXT
string text text (chave primária: varchar(255) — MySQL exige comprimento para indexar) TEXT
int/integer, long integer/bigint int/bigint INTEGER
decimal (precision/scale) numeric(p,s) exato decimal(p,s) exato sem tipo decimal nativo — vira TEXT com o conversor exato do próprio EF Core Sqlite (não REAL); round-trip do valor é exato, mas ORDER BY/comparação via SQL cru contra a coluna é lexicográfico, não numérico (db.query/sort: continua correto — o EF Core Sqlite registra uma collation EF_DECIMAL para isso)
bool/boolean boolean tinyint(1) INTEGER
datetime timestamp datetime(6) TEXT
timestamptz timestamptz — perde o offset original: todo timestamptz normaliza para UTC internamente (armazenamento, não conversão) em todos os três providers; instante e fração de segundo sobrevivem exatos, o offset não datetime(6) UTC — mesma perda de offset; fração de segundo preservada TEXT ISO-8601 — mesma perda de offset
jsonb/json jsonb/json nativos json nativo (não distingue jsonb) sem tipo JSON nativo — vira TEXT

db.sql (o escape hatch) não tem acesso ao tipo declarado da coluna — quem escreve o SQL cru é responsável por qualquer cast/collation que o dialeto do banco exigir (ex.: @id::uuid no Postgres; COLLATE NOCASE para comparar um uuid no SQLite, já que o driver o grava como TEXT em maiúsculas).

spec.caches

caches:
  - { id: redis-main, provider: redis, connectionString: "${config:Redis}", failOpen: true }
Campo Tipo Obrigatório Descrição
id string sim Identificador do cache, referenciado pelos steps cache.* e pelo bloco cache: da rota
provider string sim Qual implementação: redis (referência) ou uma chave de terceiro
connectionString string depende do provider String de conexão
failOpen boolean não Quando true, uma falha do backend de cache é tratada como cache miss em vez de derrubar a requisição — recomendado

Só um recurso de cache por aplicação — a rota e os steps cache.* nunca referenciam qual, apenas declaram cache:/cache: <id>.

spec.brokers e spec.events

brokers:
  - { id: rabbit-main, provider: rabbitmq, connectionString: "${config:Rabbit}" }
  - { id: kafka-main,  provider: kafka,    bootstrapServers: "${config:Kafka}" }

events:
  - name: OrderCreated
    schema: Orders.OrderCreated        # nome de uma entrada de spec.schemas
    broker: kafka-main
    topic: orders.v1
    partitionKey: "payload.customerId"
    description: Emitido quando um pedido é aceito
Campo Tipo Obrigatório Descrição
brokers[].id string sim Identificador do broker, referenciado por events[].broker e spec.consumers[].source
brokers[].provider string sim Qual implementação: rabbitmq, kafka (referência) ou uma chave de terceiro
brokers[].connectionString / .bootstrapServers string depende do provider Endereço do broker
events[].name string sim Nome do evento, referenciado pelo step publish
events[].schema string (nome de uma entrada de spec.schemas) não Não é um caminho de arquivo — é o name de um schema declarado em spec.schemas, alimentando o AsyncAPI gerado. Diferente de request.body.schema numa rota, este não é validado no build: um nome inexistente não falha nada, só produz um AsyncAPI sem o schema
events[].broker string sim Referência a um item de brokers
events[].topic string sim Tópico/routing key de destino
events[].partitionKey expressão JSONata não Chave de particionamento, avaliada sobre o payload publicado
events[].description string não Alimenta o AsyncAPI gerado

spec.storages

Os recursos de blob storage que os steps storage.* referenciam por id. Ver Blob storage para o uso ponta a ponta.

storages:
  - id: docs
    provider: s3
    config:
      endpoint: "${config:Storage:Endpoint}"
      region: us-east-1
      bucket: docs
      accessKeyId: "${secret:env:STORAGE_ACCESS_KEY}"
      secretAccessKey: "${secret:env:STORAGE_SECRET_KEY}"
      forcePathStyle: true
Campo Tipo Obrigatório Descrição
id string sim Identificador do storage, referenciado pelo campo storage: dos steps storage.*
provider string sim Qual implementação: s3 (que cobre AWS S3, MinIO e RustFS — mesmo protocolo) ou uma chave de terceiro
config objeto livre depende do provider Configuração do provider. O core não valida seus campos; quem valida é o próprio provider, no build

Campos de config aceitos pelo provider s3:

Campo Obrigatório Descrição
bucket sim Bucket de destino
endpoint não Endereço do serviço. Obrigatório para MinIO/RustFS; omitido, usa o endpoint padrão da AWS para a region
region não Região AWS
accessKeyId / secretAccessKey não Credenciais. Precisam ser ${secret:...} — um literal é recusado no startup. Omitidas, o SDK usa a cadeia de credenciais padrão da AWS
forcePathStyle não true para endereçamento por caminho, tipicamente exigido por MinIO e RustFS

spec.integrations

integrations:
  - id: pricing
    kind: http
    baseUrl: "${config:Pricing:Url}"
    auth: { scheme: oauth2-client-credentials, ref: corp-idp }
    resilience:
      timeout: { perAttempt: 2s, total: 8s }
      retry:   { attempts: 3, backoff: { initial: 200ms, jitter: true }, on: [502, 503, 504] }
      circuitBreaker: { failureRatio: 0.5, samplingDuration: 30s, minimumThroughput: 20, breakDuration: 15s }
      fallback: { expr: "{ 'price': 0, 'degraded': true }" }
      rateLimiter: { permitLimit: 50, window: 1s, queueLimit: 10 }
Campo Tipo Obrigatório Descrição
id string sim Identificador da integração, referenciado pelos steps http.call/grpc.call
kind http | grpc sim Protocolo da integração
baseUrl string sim URL base do sistema externo
auth.scheme / .ref string não Esquema de autenticação de saída — reusa os mesmos esquemas de spec.auth, mais oauth2-client-credentials
resilience.timeout.perAttempt / .total duração não Tempo máximo de uma tentativa, e da operação inteira (incluindo retries)
resilience.retry.attempts integer não Número de tentativas
resilience.retry.backoff.initial / .max / .jitter duração / duração / boolean não Backoff entre tentativas
resilience.retry.on lista de integer não Status HTTP que disparam retry
resilience.circuitBreaker.failureRatio number não Proporção de falhas que abre o circuito
resilience.circuitBreaker.samplingDuration duração não Janela de amostragem para o cálculo da proporção
resilience.circuitBreaker.minimumThroughput integer não Mínimo de chamadas na janela para o cálculo ser considerado significativo
resilience.circuitBreaker.breakDuration duração não Por quanto tempo o circuito fica aberto
resilience.fallback.expr expressão JSONata não Valor substituto quando a chamada falha mesmo depois de retry/circuit breaker
resilience.fallback.pipeline lista de step não Alternativa a expr: um sub-pipeline inteiro executado como fallback
resilience.rateLimiter.permitLimit integer não Limite de chamadas concorrentes/por janela
resilience.rateLimiter.window duração não Janela de tempo do limite
resilience.rateLimiter.queueLimit integer não Fila opcional para chamadas que excedem o limite instantâneo

Um status 5xx (ou uma falha de rede) que sobrevive a todo o pipeline de resiliência executa fallback, se declarado. Um status 4xx é sempre erro de negócio — nunca é repetido e nunca aciona fallback. Ver Integrações outbound.

spec.schemas

schemas:
  - name: OrderItem
    properties:
      - { name: sku,      type: string, required: true }
      - { name: quantity, type: int,    required: true }

  - name: OrderCreatePayload
    properties:
      - { name: customerId, type: uuid,          required: true }
      - { name: items,      type: "OrderItem[]", required: true }   # lista: sufixo [], não "array"
Campo Tipo Obrigatório Descrição
name string sim Nome do schema. É por ele que request.body.schema/response.schema referenciam, e é dele que sai o nome do record C# gerado
properties[].name string sim Nome do campo
properties[].type string sim Um de: string, int/int32, long/int64, double, decimal, bool/boolean, uuid, datetime/date-time; o name de outro schema; ou qualquer um deles com o sufixo [] para lista
properties[].required boolean não Se o campo é obrigatório

array não é um tipo válido — uma lista se escreve com o sufixo [] (string[], OrderItem[]). Um token desconhecido não quebra o build: o campo vira JsonNode? sem tipo e o gerador emite o diagnóstico PV3020, então repare nesse aviso em vez de assumir que passou.

Steps do pipeline

Todo step, em qualquer pipeline (de uma rota ou de um consumidor), aceita três campos universais:

Campo Tipo Obrigatório Descrição
type string sim A chave que resolve qual implementação executa
id string não Publica o resultado do step em steps.<id>.result
when expressão JSONata não O step só executa se a expressão for verdadeira. Mais barato que branch para pular um único step

Os campos específicos de cada type: — validate, map, db.persist, cache.get, publish, http.call, e todos os demais — estão documentados na referência de steps, gerada a partir do código, e com exemplos no guia. Os seis steps de controle de fluxo (branch, switch, foreach, parallel, try, group) são sintaxe estrutural do próprio motor de pipeline, cobertos em Controle de fluxo.