skip to content

In a web framework's serializer configuration, what does a naming strategy do, and why set it globally?

level: juniorimportance: must knowfreq 62%

answer

  1. one rule for every key
  2. code names versus wire names
  3. applies on read, not just write
  4. explicit per-property name wins

basics

~20 s

A naming strategy is the rule that converts property names in code into key names in the document, and back on read. Setting it on the shared serializer makes one decision cover every payload instead of repeating it per field.

solid answer

~40 s

A serializer must decide what key each property becomes. A naming strategy is that rule expressed once on the serializer instance — `as declared`, camelCase, snake_case, kebab-case and so on — and it applies to every type the instance touches, including models nobody has written yet. It is symmetric: the same rule decides which incoming key binds to which property, so it governs request binding as much as response output. Individual properties can still declare an explicit key, and that declaration wins, which is the intended escape hatch for names the convention cannot produce. Expressing the house convention only as per-property renames is the anti-pattern: the convention then lives in hundreds of repetitions rather than one place, and the next model quietly forgets it.

go deeper

for a junior

Be able to say that a naming strategy maps property names in code to key names in the document, and to name two conventions it can produce, such as camelCase and snake_case.

for a middle

Explain that the rule runs on read as well as write, that an explicit per-property key takes precedence, and that the setting belongs to the serializer instance rather than to any model.

for a senior

Show that you treat a strategy switch as a contract change with a rollout: aliases accepted on read first, then the write flip, with stored sample documents guarding each endpoint.

for a principal

Take a position on where the convention is owned across many services, what is enforced by a shared configuration artefact versus by review, and what an inherited legacy convention is allowed to cost.

## What a naming strategy is A serializer turns an in-memory object into a document and back again. The object exposes **properties** whose names follow the conventions of the code base; the document carries **keys** whose names follow the conventions of the API. A **naming strategy** is the rule that maps one onto the other: a function applied to every property name when a document is written, and applied again — then matched against the incoming keys — when a document is read. Strategies in common use: - **as declared** — the key is the property name, character for character; - **camelCase** — `orderId`; - **snake_case** — `order_id`; - **kebab-case** — `order-id`; - **PascalCase** — `OrderId`; - **upper snake** — usually only to satisfy an inherited contract. The crucial structural point is that the strategy belongs to the **serializer instance**, not to any one model. Set it once on the instance the framework holds at its boundary and every payload the service reads or writes obeys it, including payloads for models nobody has written yet. ## Why it is set globally rather than field by field Every serializer also lets a single property declare its own wire name explicitly. Both mechanisms exist and they answer different questions: | Mechanism | Scope | What it is for | Failure mode | |---|---|---|---| | Global naming strategy | every type the instance touches | the house convention of the whole API | flipping it changes every endpoint at once | | Per-property name override | one property | a name the convention cannot produce, or an inherited key | multiplies quietly; nobody reviews four hundred of them | | Per-type override | one model | a model bound to a foreign contract | two conventions inside one API surface | If the house convention exists only as per-property overrides, then it does not exist as a decision at all — it exists as several hundred repetitions of a decision, and the next model somebody adds simply forgets it. That is the drift a global setting prevents, and it is the reason this is one line in the shared configuration rather than a review habit. ## The rule is symmetric, and that is the part people forget Because the same strategy is consulted on read, it decides which incoming keys bind to which properties. Two consequences follow. 1. Flipping the strategy is a change to the **request** contract as much as the response contract. Clients that were sending the old spelling now send keys the reader does not recognise. 2. The effect of that depends on a *different* setting on the same instance — whether an unmatched key is rejected or ignored. Combined with an ignoring policy, a strategy flip fails silently: requests still return success, and every renamed field simply arrives unset. That pairing is the classic incident. The strategy change is reviewed as cosmetic, the ignore policy hides the breakage, and the symptom surfaces later as missing data rather than as an error. ## Where the strategy stops - **Explicit names win.** A property that declares its own key is not transformed; precedence runs from the most specific declaration outward. This is the intended escape hatch for the handful of keys the convention cannot express. - **Dynamic map keys are data.** When a property is a map whose keys are supplied at runtime, most serializers leave those keys untouched, because they are values rather than declared property names. That is usually what you want, and it surprises people who expected a uniformly cased document. - **Acronyms and digits are where strategies genuinely disagree.** Names like `orderID`, `httpURL` or `line1` split differently depending on how the strategy tokenises. Two sides of a wire that both claim "snake_case" can still disagree on `order_i_d` versus `order_id`. Pin the result with a test over a real sample document instead of trusting the strategy's label. - **Names must be available at all.** Where a runtime does not retain parameter or property names in compiled metadata, the serializer has nothing to transform and falls back to declared names or positional binding; the strategy then appears to do nothing for constructor-bound models. ## Treat a change as a wire change Because it applies to everything at once, the naming strategy has the widest blast radius of any line in a serializer configuration. A safe migration is staged rather than flipped: 1. teach the reader both spellings (aliases on the old keys) and deploy that first; 2. flip the write side once consumers report readiness; 3. remove the aliases after the agreed window. Back the whole thing with stored sample documents per endpoint, compared byte for byte in a test, so that any future change to the shared instance fails the build rather than a consumer.

  • One key must differ from what the strategy would produce. What is the cleanest way to express that?
    Declare the explicit key on that one property. It takes precedence over the strategy, and it leaves the global convention intact so the exception is visible as an exception. Switching the whole instance, or renaming every sibling property to match, turns one irregular key into a second convention.
  • How would you migrate an API from one key convention to another without a flag day?
    Stage it. First teach the reader both spellings by aliasing the old keys, and deploy that alone. Then flip the write side once consumers are ready. Remove the aliases after an agreed window. Back each step with stored sample documents compared in a test, since an ignore-unknown-key policy would otherwise hide the breakage.

saying these in an interview costs you the question

  • Thinks the naming strategy affects responses only, not request binding.
  • Renames every field with a per-property override and calls that the convention.
  • Assumes two serializers both labelled snake_case agree on acronyms and digits.
  • Treats flipping the strategy as an internal refactor rather than a contract change.
  • Expects runtime-supplied map keys to be rewritten by the strategy.