skip to content

Your organisation wants one interface-style standard for every new service surface; would you mandate a single style among RPC, REST, GraphQL and messaging, and why?

level: principalimportance: should knowfreq 9%

answer

  1. standardise the decision, not the answer
  2. consumer decides the default
  3. a mismatch tax versus a sprawl tax
  4. exceptions with a written reason

basics

~20 s

Usually not one style. Standardise the decision: a default per consumer - REST for public and partner HTTP, an IDL-based RPC framework internally, GraphQL for client-composed views, messaging where no immediate answer is needed - plus shared conventions and a recorded exception path.

solid answer

~50 s

I would standardise the **decision** rather than one answer. Forcing one style everywhere imposes a mismatch tax: GraphQL for file downloads, REST for streaming, RPC for browser and partner clients that then need a proxy. Allowing anything imposes a sprawl tax: several toolchains, gateways, security reviews and error models to maintain. So the standard names a default per consumer - REST described in OpenAPI for public and partner surfaces, an RPC framework with a shared IDL for internal calls, GraphQL only where client teams compose many entities per screen, and messaging where the caller does not need the outcome now - and requires a short written reason for any exception. It also fixes what every style must share: contract-first descriptions, an error model, versioning rules, authentication and observability, and an approved way to give one service a second face rather than re-implementing it.

go deeper

for a junior

Recall that different consumers - browsers, partners, internal services, background jobs - tend to fit different interface styles.

for a middle

Explain why a one-style mandate creates misfits for some operations and what conventions should hold across all styles regardless.

for a senior

Show how you would give an existing service a second face for a new audience, and what error and streaming mapping that costs.

for a principal

Price the mismatch tax against the sprawl tax, set defaults by consumer, and design an enforceable exception process the organisation will actually use.

## What the question is really asking An organisation-wide standard trades local freedom for global consistency. The question tests whether a candidate can see both costs and design a rule that keeps most of the benefit of each. There is no single correct answer, but there are clearly weak ones: "always REST because it is standard", "always gRPC because it is fast", "let every team choose". ## The two taxes | | Mandate one style | Allow any style | |---|---|---| | Consistency for consumers | high | low | | Fit for each operation | often poor | good | | Toolchains, gateways, linters to run | one | several | | Security reviews and threat models | one pattern | one per style | | Hiring and onboarding | simple | broader skills needed | | Typical failure | a mismatch tax: streaming forced into polling, browsers behind a translating proxy, files pushed through a query language | a sprawl tax: four error models, three auth schemes, no shared client tooling | ## Standardise the decision, not the answer A workable standard has three parts. **1. A default per consumer type.** - **Public and partner surfaces** default to **REST** with an OpenAPI description: any HTTP client can call it, browsers reach it directly, and HTTP caching and status codes work for unknown callers. - **Internal request/response contracts between services the organisation owns** default to an **RPC framework with a shared IDL**: generated clients, typed contracts, efficient encodings and streaming where needed. - **Client applications composing many related entities per screen** may use **GraphQL**, owned by a team that can operate it - query cost limits, field-level authorisation, schema review. - **Work where the caller does not need the outcome now** - long-running jobs, fan-out of facts to many consumers - goes through **messaging**, with message schemas in a registry. **2. Shared conventions that every style must meet.** 1. A contract-first description committed beside the code (an OpenAPI document, a `.proto`, a GraphQL schema, a message schema). 2. One error model in spirit: a machine-readable code, a human message, and structured details, mapped onto each style's own mechanism. 3. Versioning and deprecation rules, including how long an old version is served. 4. Authentication, authorisation and observability that work the same way whatever the style. **3. An exception path.** A team that needs a different style writes a short decision record: the operation, the consumers, why the default fails, and who will run the extra tooling. Most exceptions are legitimate - a real-time feed, a partner who requires SOAP - and the record keeps them visible. ## One service, two faces The standard should also say how a service reaches a second audience without being rewritten. Options include: - an RPC service given an HTTP/JSON face by declaring HTTP mappings on its methods and running a transcoder in front; - a GraphQL layer whose resolvers call existing RPC or REST services; - a synchronous API that accepts a request and publishes a command for the slow work behind it. Each extra face costs something - error mapping, streaming that does not translate, a contract that now has two shapes - so the standard should name who owns that mapping. ## What a principal is judged on - **Naming the consumers first.** The right style follows from who calls and what they need, not from fashion. - **Pricing both taxes.** The cost of a misfit style and the cost of style sprawl, in people and tooling. - **Making the rule enforceable.** Linters on contracts, a review gate on new surfaces, a catalogue of which service exposes which style. - **Planning the transition.** Existing surfaces in other styles get a review date rather than a forced rewrite, because a rewrite pays the full cost with no new benefit to their consumers. - **Revisiting it.** A standard written for one set of consumers needs review when those change - a new partner channel, a mobile client, an agent ecosystem speaking another protocol. ## A short answer to give "I would not mandate one style. I would mandate one way of choosing: a default per consumer, a common set of conventions every style meets, and a cheap, visible exception process - because both the misfit and the sprawl are real costs, and the standard's job is to keep each one small."

  • A team asks to use GraphQL for an internal service called only by two other services. How would you rule under such a standard?
    Probably decline and point them to the internal default. GraphQL's main gain is letting many client views select their own fields; two known service callers rarely need that, while the team would take on query cost limits, field-level authorisation and a separate toolchain. If they can show varied, client-driven selections that the default handles badly, the exception record is the place to make that case.
  • How do you keep error handling consistent when the organisation runs several styles?
    Define one error model conceptually - a stable machine-readable code, a human message and structured details - and specify how it maps onto each style's mechanism: HTTP status plus a problem-details body for REST, the framework's status and details for RPC, the errors list for GraphQL, a failure event for messaging. Publish the mappings so that a gateway or a second face translates errors without losing the code.

saying these in an interview costs you the question

  • Mandating one style everywhere is free once the tooling is chosen.
  • The fastest wire protocol should be the default for every consumer, including partners.
  • Letting each team pick its own style has no organisational cost.
  • An exception to the standard is a failure rather than a recorded, reviewed decision.
  • GraphQL should replace REST for all public APIs because clients pick their fields.