REST Lens
← Back to All Rules
Rule 76

Allowed Dictionary

Category: Naming Conventions

Description

Enforces consistent domain vocabulary across your API by validating that path segments, parameters, and schema property names only use terms from an explicitly allowed dictionary.

What It Checks

This rule validates API naming elements against a custom vocabulary list you define. It intelligently splits names across various naming conventions (camelCase, snake_case, kebab-case, PascalCase) and checks each word against your allowed terms.

The rule can check three types of API elements:

  • Path segments: Resource names in URI paths (e.g., users, orders, products)
  • Parameters: Query parameters, path parameters, and header parameter names
  • Schema property keys: JSON request/response body property names

The rule intelligently handles different naming conventions:

  • snake_case: user_profile → ["user", "profile"]
  • camelCase: userId → ["user", "id"]
  • PascalCase: UserProfile → ["user", "profile"]
  • kebab-case: user-profile → ["user", "profile"]
  • UPPER_SNAKE_CASE: USER_ID → ["user", "id"]

Why It Matters

Enforcing a controlled vocabulary improves API quality and maintainability:

  • Consistency: Prevents naming variations (user vs account, remove vs delete)
  • Domain alignment: Ensures API uses standardized business terminology
  • Team coordination: Enforces agreed-upon vocabulary across multiple developers
  • Onboarding: New developers learn the domain vocabulary through the API design
  • Documentation quality: Consistent terms make documentation clearer and easier to maintain

Examples

Good ✅

With configuration:

allowed_terms: user,account,id,name,email,create,update,delete,status,active
check_paths: true
check_parameters: true
check_schema_keys: true
paths:
  /users:
    get:
      summary: List users
      parameters:
        - name: status
          in: query
          schema:
            type: string
      responses:
        '200':
          description: User list
          content:
            application/json:
              schema:
                type: object
                properties:
                  users:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        name:
                          type: string
                        email:
                          type: string
                        status:
                          type: string

  /accounts/{accountId}:
    put:
      summary: Update account
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                active:
                  type: boolean

All terms used (users, status, id, name, email, accounts, accountId, active) are in the allowed dictionary.

Bad ❌

With the same configuration as above:

paths:
  /customers:  # ❌ 'customers' not in allowed dictionary
    get:
      summary: List customers
      parameters:
        - name: filter  # ❌ 'filter' not in allowed dictionary
          in: query
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:  # ❌ 'data' not in allowed dictionary
                    type: array
                    items:
                      type: object
                      properties:
                        customerId:  # ❌ 'customer' not in allowed dictionary
                          type: string
                        fullName:  # ❌ 'full' not in allowed dictionary
                          type: string

Violations:

  • Path segment customers contains disallowed term: customers
  • Parameter filter contains disallowed term: filter
  • Schema property data contains disallowed term: data
  • Schema property customerId contains disallowed term: customer
  • Schema property fullName contains disallowed term: full

Configuration

This is a configurable rule with the following options:

allowed_terms (required)

Comma-separated list of allowed vocabulary terms (case-insensitive).

  • Type: Freeform string (comma-separated values)
  • Default: "" (empty, rule is effectively disabled)
  • Example: "user,account,id,name,email,create,update,delete,status,active,role,permission"

Important: If allowed_terms is empty or not set, the rule allows all names (effectively disabled).

check_paths (optional)

Whether to validate path segment names against the dictionary.

  • Type: Boolean ("true" or "false")
  • Default: "true"
  • Example: Set to "false" to skip checking path segments

check_parameters (optional)

Whether to validate parameter names against the dictionary.

  • Type: Boolean ("true" or "false")
  • Default: "true"
  • Example: Set to "false" to skip checking parameters

check_schema_keys (optional)

Whether to validate schema property names against the dictionary.

  • Type: Boolean ("true" or "false")
  • Default: "true"
  • Example: Set to "false" to skip checking JSON schema properties

Configuration Examples

Minimal configuration (check everything):

{
  "allowed_terms": "user,account,id,name,email,status"
}

Check only paths and parameters (not schema keys):

{
  "allowed_terms": "user,account,id,name,email,status",
  "check_paths": "true",
  "check_parameters": "true",
  "check_schema_keys": "false"
}

Check only schema properties:

{
  "allowed_terms": "user,account,id,name,email,status",
  "check_paths": "false",
  "check_parameters": "false",
  "check_schema_keys": "true"
}

Comprehensive domain vocabulary:

{
  "allowed_terms": "user,account,customer,id,name,email,phone,address,city,state,country,zip,postal,code,create,update,delete,get,list,search,filter,sort,page,limit,offset,status,active,inactive,enabled,disabled,role,permission,admin,member,owner,organization,project,team,created,updated,deleted,at,by,date,time,timestamp",
  "check_paths": "true",
  "check_parameters": "true",
  "check_schema_keys": "true"
}

How to Fix

Step 1: Define Your Domain Vocabulary

Create a list of all valid business terms for your API domain:

# Core entities
user, account, customer, organization, team, project

# Identifiers and attributes
id, name, email, phone, address, description, title

# Actions/verbs
create, update, delete, get, list, search, filter, validate

# Status/state
status, active, inactive, enabled, disabled, pending, approved

# Common technical terms
page, limit, offset, sort, order, data, metadata, timestamp

Step 2: Configure the Rule

Add your allowed terms to the rule configuration:

{
  "allowed_terms": "user,account,organization,id,name,email,status,active,create,update,delete",
  "check_paths": "true",
  "check_parameters": "true",
  "check_schema_keys": "true"
}

Step 3: Fix Violations

For each violation, either:

Option A: Add the term to your dictionary (if it's valid domain vocabulary):

{
  "allowed_terms": "user,account,organization,customer,id,name,email"
  // Added 'customer' to allowed terms
}

Option B: Rename to use allowed terms:

# Before (using disallowed term 'client')
/clients/{clientId}

# After (using allowed term 'customer')
/customers/{customerId}

Step 4: Handle Compound Terms

The rule splits names into words, so ensure all word components are in your dictionary:

# For 'userProfile' you need both 'user' and 'profile' in allowed_terms
# For 'created_at' you need both 'created' and 'at' in allowed_terms

allowed_terms: "user,profile,created,at,updated,deleted,by,id"

Step 5: Selective Checking

If you want to enforce vocabulary only in specific areas:

{
  "allowed_terms": "user,account,id,name",
  "check_paths": "true",
  "check_parameters": "true",
  "check_schema_keys": "false"  // Don't check schema properties
}

Exceptions and Edge Cases

Path Parameters Are Not Checked

Path parameter names (variables in curly braces) are skipped for path checking:

/users/{userId}  # 'users' is checked, '{userId}' is skipped for path check
                 # but 'userId' IS checked if check_parameters is true

Root Path Ignored

The root path / is automatically ignored and won't trigger violations.

Case Insensitivity

All comparisons are case-insensitive:

{
  "allowed_terms": "user,id"  // Will match User, USER, UserId, user_id, etc.
}

Empty Dictionary Disables Rule

If allowed_terms is empty or contains only whitespace, the rule allows all names:

{
  "allowed_terms": ""  // Rule is effectively disabled
}

Related Rules

  • Rule 75: Consistent Naming Conventions - Enforces naming pattern consistency across the API
  • Rule 26: Hyphens vs Underscores - Controls word separators in URI paths
  • Rule 28: Lowercase Letters - Enforces lowercase in URI paths