Skip to content
Knowledge Hub

Naming REST APIs, events, Kafka topics, env vars and git branches Basic

Estimated reading time: 4 min read

This page answers: how to name the things that leave the process (endpoints, JSON, events, topics, env vars, branches). These are contracts with other people, so renaming them later is very expensive.

REST APIs: plural nouns, verbs only for actions

Section titled “REST APIs: plural nouns, verbs only for actions”
Rule Before After
Collections are plural nouns GET /getOrders, GET /order GET /orders
Multi-word path segments /paymentMethods, /payment_methods /payment-methods
JSON fields camelCase, abbreviations as words { "order_ID": 1, "CustomerName": "..." } { "orderId": 1, "customerName": "..." }
CRUD uses HTTP methods POST /orders/delete/42 DELETE /orders/42
Non-CRUD actions POST /orders/42/do-cancel-order POST /orders/42:cancel or POST /orders/42/cancel
Lists POST /api/getOrderList GET /api/orders

The two big guidelines disagree on path segments:

Microsoft Azure REST Guidelines Google AIP-122 / AIP-136
Path segment kebab-case (preferred) or camelCase plural camelCase collection IDs (publishers/123/books)
JSON field camelCase AIP-140: lower_snake_case in proto, mapped to the JSON convention
Action POST /<collection>/<id>:<action>, only when CRUD cannot express it custom method :archive, GET or POST

Suggested default for public HTTP/JSON APIs: kebab-case paths, camelCase JSON. More important than the choice is that one API uses only one style. Error bodies need stable field names too: see Problem Details RFC 9457.

An event is a fact that has happened: name it in the past tense, in the language of the domain (OrderPlaced, PaymentCaptured). An imperative name like CreateInvoice is a command: it requests something and can be rejected.

Loading diagram…

Before Problem After
OrderUpdated Does not say what changed; consumers have to diff OrderShippingAddressChanged
PaymentEvent with a type field One name for everything PaymentCaptured, PaymentRefunded
SendEmail on an event topic It is a command, not an event CustomerRegistered (the email service decides whether to send)
order_status_9 Internal code leaking out OrderCancelled

Topics are a team convention; Kafka imposes no structure. An easy-to-operate pattern: <domain>.<event-or-entity>.v<major>, e.g. billing.payment-captured.v1. A version in the name lets v1 and v2 run side by side when the schema changes incompatibly.

Real constraints from Kafka (per Topic.java):

  • Only the characters [a-zA-Z0-9._-], at most 249 characters.
  • Topics that differ only by . versus _ in the same position can collide in metric names. Pick one separator and do not mix.

Choosing keys for a topic: see Kafka message keys and ordering.

POSIX specifies that environment variables used by standard utilities consist only of uppercase letters, digits and _ and do not start with a digit. Follow the same style, adding a group prefix and a unit suffix:

Terminal window
# Before
dbHost=...
TIMEOUT=30
KEY=sk_live_...
# After
DATABASE_URL=postgres://...
PAYMENT_API_TIMEOUT_MS=30000
PAYMENT_API_SECRET_KEY=...
FEATURE_NEW_CHECKOUT_ENABLED=true
  • Prefix (PAYMENT_, FEATURE_): groups keys for config validation at startup, easy to grep.
  • Unit suffix (_MS, _BYTES): same reason as in code.

Pattern: type/ticket-id-short-description, lowercase, hyphens.

Branch Meaning
feat/PAY-210-partial-refund New feature, ticket PAY-210
fix/ORD-88-duplicate-webhook Bug fix, ticket ORD-88
chore/bump-node-24 Maintenance work

The ticket ID connects the branch to the reason for the change; the type (feat, fix, chore) helps filtering in CI. For the full branch workflow see Git workflow.

Next: Common mistakes.