Targeting Rules
Gerenciamento de regras de targeting para controle granular de rollout de feature flags.
Endpoints
| Método | Endpoint | Descrição | Permissão |
|---|---|---|---|
| POST | /api/v1/feature-flags/:flagId/targeting-rules | Criar regra | FEATURE_FLAGS_UPDATE |
| GET | /api/v1/feature-flags/:flagId/targeting-rules | Listar regras | FEATURE_FLAGS_READ |
| GET | /api/v1/feature-flags/:flagId/targeting-rules/:id | Obter regra | FEATURE_FLAGS_READ |
| PATCH | /api/v1/feature-flags/:flagId/targeting-rules/:id | Atualizar regra | FEATURE_FLAGS_UPDATE |
| DELETE | /api/v1/feature-flags/:flagId/targeting-rules/:id | Excluir regra | FEATURE_FLAGS_UPDATE |
| POST | /api/v1/feature-flags/:flagId/targeting-rules/reorder | Reordenar regras | FEATURE_FLAGS_UPDATE |
Atributos
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | Sim | Nome da regra (max 200 caracteres) |
description | string | Não | Descrição (max 1000 caracteres) |
priority | integer | Não | Prioridade de avaliação (default: proximo disponivel) |
variationKey | string | Sim | Key da variação a retornar quando a regra faz match |
rolloutPercentage | integer | Não | Porcentagem de rollout (0-100, default: 100) |
segmentIds | array (UUID) | Não | IDs dos segmentos que devem fazer match (lógica AND) |
inlineDmnRule | string | Não | Regra DMN inline (alternativa a segmentIds) |
Criar Targeting Rule
POST /api/v1/feature-flags/:flagId/targeting-rules
Cria uma nova regra de targeting para uma feature flag.
Request
- cURL
- JavaScript
curl -X POST 'https://feature-flags.stg.catalisa.app/api/v1/feature-flags/550e8400-e29b-41d4-a716-446655440000/targeting-rules' \
-H 'Authorization: Bearer SEU_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"name": "Premium users get new feature",
"description": "Libera variação on para 50% dos usuários premium",
"variationKey": "on",
"rolloutPercentage": 50,
"segmentIds": ["550e8400-e29b-41d4-a716-446655440001"]
}'
const flagId = '550e8400-e29b-41d4-a716-446655440000';
const response = await fetch(`https://feature-flags.stg.catalisa.app/api/v1/feature-flags/${flagId}/targeting-rules`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Premium users get new feature',
description: 'Libera variação on para 50% dos usuários premium',
variationKey: 'on',
rolloutPercentage: 50,
segmentIds: ['550e8400-e29b-41d4-a716-446655440001'],
}),
});
const { data } = await response.json();
Response (201 Created)
{
"data": {
"type": "targeting-rules",
"id": "550e8400-e29b-41d4-a716-446655440002",
"attributes": {
"name": "Premium users get new feature",
"description": "Libera variação on para 50% dos usuários premium",
"priority": 0,
"variationKey": "on",
"rolloutPercentage": 50,
"segmentIds": ["550e8400-e29b-41d4-a716-446655440001"],
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
},
"links": {
"self": "/api/v1/feature-flags/550e8400-e29b-41d4-a716-446655440000/targeting-rules/550e8400-e29b-41d4-a716-446655440002"
}
}
}
Listar Targeting Rules
GET /api/v1/feature-flags/:flagId/targeting-rules
Lista todas as regras de targeting de uma feature flag, ordenadas por prioridade.
- cURL
- JavaScript
curl 'https://feature-flags.stg.catalisa.app/api/v1/feature-flags/550e8400-e29b-41d4-a716-446655440000/targeting-rules' \
-H 'Authorization: Bearer SEU_TOKEN'
const flagId = '550e8400-e29b-41d4-a716-446655440000';
const response = await fetch(`https://feature-flags.stg.catalisa.app/api/v1/feature-flags/${flagId}/targeting-rules`, {
headers: {
'Authorization': `Bearer ${token}`,
},
});
const { data } = await response.json();
Response (200 OK)
{
"data": [
{
"type": "targeting-rules",
"id": "550e8400-e29b-41d4-a716-446655440002",
"attributes": {
"name": "Premium users get new feature",
"priority": 0,
"variationKey": "on",
"rolloutPercentage": 50,
"segmentIds": ["550e8400-e29b-41d4-a716-446655440001"]
}
},
{
"type": "targeting-rules",
"id": "550e8400-e29b-41d4-a716-446655440003",
"attributes": {
"name": "Beta testers full rollout",
"priority": 1,
"variationKey": "on",
"rolloutPercentage": 100,
"segmentIds": ["550e8400-e29b-41d4-a716-446655440004"]
}
}
]
}
Obter Targeting Rule
GET /api/v1/feature-flags/:flagId/targeting-rules/:id
Obtém detalhes de uma regra de targeting específica.
- cURL
- JavaScript
curl 'https://feature-flags.stg.catalisa.app/api/v1/feature-flags/550e8400-e29b-41d4-a716-446655440000/targeting-rules/550e8400-e29b-41d4-a716-446655440002' \
-H 'Authorization: Bearer SEU_TOKEN'
const flagId = '550e8400-e29b-41d4-a716-446655440000';
const ruleId = '550e8400-e29b-41d4-a716-446655440002';
const response = await fetch(`https://feature-flags.stg.catalisa.app/api/v1/feature-flags/${flagId}/targeting-rules/${ruleId}`, {
headers: {
'Authorization': `Bearer ${token}`,
},
});
const { data } = await response.json();
Response (200 OK)
{
"data": {
"type": "targeting-rules",
"id": "550e8400-e29b-41d4-a716-446655440002",
"attributes": {
"name": "Premium users get new feature",
"description": "Libera variação on para 50% dos usuários premium",
"priority": 0,
"variationKey": "on",
"rolloutPercentage": 50,
"segmentIds": ["550e8400-e29b-41d4-a716-446655440001"],
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
},
"links": {
"self": "/api/v1/feature-flags/.../targeting-rules/..."
}
}
}
Atualizar Targeting Rule
PATCH /api/v1/feature-flags/:flagId/targeting-rules/:id
Atualiza uma regra de targeting existente.
- cURL
- JavaScript
curl -X PATCH 'https://feature-flags.stg.catalisa.app/api/v1/feature-flags/550e8400-e29b-41d4-a716-446655440000/targeting-rules/550e8400-e29b-41d4-a716-446655440002' \
-H 'Authorization: Bearer SEU_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"rolloutPercentage": 100,
"description": "Full rollout para usuários premium"
}'
const flagId = '550e8400-e29b-41d4-a716-446655440000';
const ruleId = '550e8400-e29b-41d4-a716-446655440002';
const response = await fetch(`https://feature-flags.stg.catalisa.app/api/v1/feature-flags/${flagId}/targeting-rules/${ruleId}`, {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
rolloutPercentage: 100,
description: 'Full rollout para usuários premium',
}),
});
const { data } = await response.json();
Response (200 OK)
{
"data": {
"type": "targeting-rules",
"id": "550e8400-e29b-41d4-a716-446655440002",
"attributes": {
"name": "Premium users get new feature",
"description": "Full rollout para usuários premium",
"rolloutPercentage": 100,
"updatedAt": "2024-01-15T11:00:00Z"
}
}
}
Excluir Targeting Rule
DELETE /api/v1/feature-flags/:flagId/targeting-rules/:id
Remove uma regra de targeting.
- cURL
- JavaScript
curl -X DELETE 'https://feature-flags.stg.catalisa.app/api/v1/feature-flags/550e8400-e29b-41d4-a716-446655440000/targeting-rules/550e8400-e29b-41d4-a716-446655440002' \
-H 'Authorization: Bearer SEU_TOKEN'
const flagId = '550e8400-e29b-41d4-a716-446655440000';
const ruleId = '550e8400-e29b-41d4-a716-446655440002';
const response = await fetch(`https://feature-flags.stg.catalisa.app/api/v1/feature-flags/${flagId}/targeting-rules/${ruleId}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`,
},
});
// Status 204 No Content = sucesso
Response (204 No Content)
Sem corpo de resposta.
Reordenar Targeting Rules
POST /api/v1/feature-flags/:flagId/targeting-rules/reorder
Reordena as regras de targeting. A ordem no array define a nova prioridade (indice 0 = prioridade 0).
- cURL
- JavaScript
curl -X POST 'https://feature-flags.stg.catalisa.app/api/v1/feature-flags/550e8400-e29b-41d4-a716-446655440000/targeting-rules/reorder' \
-H 'Authorization: Bearer SEU_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"ruleIds": [
"550e8400-e29b-41d4-a716-446655440003",
"550e8400-e29b-41d4-a716-446655440002"
]
}'
const flagId = '550e8400-e29b-41d4-a716-446655440000';
const response = await fetch(`https://feature-flags.stg.catalisa.app/api/v1/feature-flags/${flagId}/targeting-rules/reorder`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
ruleIds: [
'550e8400-e29b-41d4-a716-446655440003', // Nova prioridade 0
'550e8400-e29b-41d4-a716-446655440002', // Nova prioridade 1
],
}),
});
const { success } = await response.json();
Response (200 OK)
{
"success": true
}
Conceitos
Prioridade de Avaliação
As regras são avaliadas em ordem de prioridade (menor número = maior prioridade):
- Regra com
priority: 0e avaliada primeiro - Se fizer match e passar no rollout, retorna a variação
- Se nao fizer match, avalia regra com
priority: 1 - E assim por diante...
Lógica de Segmentos (AND)
Quando uma regra tem multiplos segmentIds, o usuário deve pertencer a todos os segmentos (lógica AND):
{
"segmentIds": ["premium-users", "brazil-users"]
}
// Usuário deve ser premium E estar no Brasil
Rollout Percentual
O rollout percentual usa hash consistente baseado no userId:
- Mesmo usuário sempre cai no mesmo bucket
- Aumentar de 10% para 50% inclui os usuários anteriores
- Sem
userId, hash e baseado em timestamp (aleatorio)
// 50% rollout
{
"rolloutPercentage": 50,
"variationKey": "on"
}
// Metade dos usuários que fazem match recebem "on"
// Outra metade continua para proxima regra ou default
Regra DMN Inline
Alternativa aos segmentos para lógica complexa:
{
"name": "Complex eligibility check",
"variationKey": "premium-experience",
"inlineDmnRule": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>..."
}
Exemplos de Cenarios
Rollout Gradual
// Semana 1: 10% dos usuários premium
{
"name": "Week 1 rollout",
"variationKey": "new-ui",
"rolloutPercentage": 10,
"segmentIds": ["premium-users"]
}
// Semana 2: 50% (update da regra)
// Semana 3: 100% (update da regra)
Beta Testing
// Prioridade 0: Beta testers recebem 100%
{
"name": "Beta testers",
"priority": 0,
"variationKey": "on",
"rolloutPercentage": 100,
"segmentIds": ["beta-testers"]
}
// Prioridade 1: Premium recebe 25%
{
"name": "Premium early access",
"priority": 1,
"variationKey": "on",
"rolloutPercentage": 25,
"segmentIds": ["premium-users"]
}
// Demais usuários: default variation
A/B Testing por Regiao
// Regra 1: Brasil vê variante A
{
"name": "Brazil variant A",
"variationKey": "variant-a",
"rolloutPercentage": 100,
"segmentIds": ["brazil-users"]
}
// Regra 2: USA vê variante B
{
"name": "USA variant B",
"variationKey": "variant-b",
"rolloutPercentage": 100,
"segmentIds": ["usa-users"]
}
Erros Comuns
| Código | Erro | Descrição |
|---|---|---|
| 400 | VALIDATION | Campos obrigatorios ausentes ou valores inválidos |
| 404 | NOT_FOUND | Feature flag ou targeting rule nao encontrada |
| 400 | VALIDATION | variationKey nao existe na flag |
| 400 | VALIDATION | segmentIds contém ID de segmento inexistente |