Why are federation's _entities and _service named with one underscore rather than two?
answer
- One prefix is reserved, the other is convention
- Introspection owns the double underscore
- Federation is a layer, not the specification
- Meta-fields are supplied, not declared
- _entities is an ordinary field of Query
basics
~20 sThe GraphQL specification reserves the double-underscore prefix for the introspection system and forbids schema authors from using it. Federation is a layer built on ordinary GraphQL, so its added members take a single underscore instead — legal, and conventionally set aside for machinery.
solid answer
~50 sGraphQL reserves names beginning with two underscores for introspection — `__schema`, `__type`, `__typename`, `__Type`, `__Field` — and tells type-system authors not to define anything with that prefix, so the introspection namespace can grow without colliding with user schemas. Federation is not part of the GraphQL specification; it is a convention a server library implements by adding ordinary schema members, so `_entities`, `_service`, `_Any` and `_Entity` must live in the normal name space. One underscore is the compromise: a visual marker for 'machinery, not domain API' that breaks no rule. The consequence worth knowing is that these really are ordinary members — `_entities` shows up as a plain field of `Query` in introspection and in an explorer's docs, and anyone who can reach the subgraph endpoint can call it, which is one reason subgraph endpoints are kept private.
code
graphql · 12 linesscalar _Any
union _Entity = Trial | Site
type _Service {
sdl: String!
}
extend type Query {
_entities(representations: [_Any!]!): [_Entity]!
_service: _Service!
}go deeper
Recall that two leading underscores belong to GraphQL introspection and are off limits to schema authors, so federation's added fields use one instead.
Explain the consequence rather than the rule: federation's members are ordinary schema members, so they introspect, appear in docs and are callable like any other field.
Use it as the way into the trust boundary — a reserved-looking name protects nothing, so a subgraph's reference resolver must enforce its own authorization and the endpoint must not be publicly reachable.
Note the general pattern for anyone designing a layer above a specification: live inside its naming rules, mark yourself by convention, and never rely on a name to imply privilege or privacy.
## The rule being obeyed The GraphQL specification carves out a namespace for itself. Introspection's meta-fields and meta-types are prefixed with two underscores — `__schema`, `__type` and `__typename` as fields, `__Type`, `__Field`, `__InputValue`, `__EnumValue`, `__Directive`, `__Schema` and `__TypeKind` as types — and the specification instructs type-system authors not to define any type, field, argument or other artefact whose name begins with `__`. The reservation is what lets introspection gain a new meta-field in a later edition without breaking a schema that happened to use that name. So the prefix is not decoration. It is a reserved namespace, and a schema that defines `__entities` is out of specification; a validating library will refuse to build it. ## Why federation is bound by that rule Apollo Federation is a composition specification layered *on top of* GraphQL, not a change to it. A federated subgraph is an ordinary GraphQL service; what makes it a subgraph is that its schema additionally contains some ordinary members: ```graphql scalar _Any union _Entity = Trial | Site type _Service { sdl: String! } type Query { _entities(representations: [_Any!]!): [_Entity]! _service: _Service! } ``` Every line of that is plain SDL a server library adds to the schema. None of it is privileged by the GraphQL execution engine, none of it is a meta-field, and so none of it may claim the reserved prefix. A single leading underscore is legal in a GraphQL name and carries no meaning to the specification at all — which makes it available as a convention. Federation uses it to say 'this member is protocol machinery, not part of the domain API', the same way many codebases use a leading underscore for internals. ## What actually follows from the distinction This is more than trivia, because the two prefixes behave differently. **Meta-fields are hidden from the type system.** `__schema` and `__type` are not listed among `Query`'s fields in an introspection result, and `__typename` is not listed on any type; the execution engine supplies them. They are not really in the schema. **Federation's fields are in the schema.** `_entities` appears as a normal field of `Query` when you introspect a subgraph, and an explorer will list it in the docs pane beside the domain fields. It is queryable by anything that can reach the endpoint. Nothing about the name makes it privileged or protected — which is why a subgraph endpoint belongs on a private network behind the router, and why a subgraph must apply its own authorization inside the reference resolver rather than assuming its root fields are the only entrance. **Names shape tooling, not behaviour.** Because the underscore convention is purely visual, tools that hide 'internal' fields do so by matching a name pattern, not by asking the schema. A schema linter, a docs generator or a client codegen tool will each need telling. ## A neighbouring naming choice The same reasoning explains why Federation 2 namespaces imported definitions rather than inventing more underscores: when a schema opts into a federation edition with `@link`, the imported directives and types get prefixed names in the schema's own namespace instead of squatting on more reserved-looking territory. The underlying principle is constant — a layer above the specification lives inside the specification's rules, and marks itself with convention rather than privilege. ## The interview-sized answer Two underscores are reserved for GraphQL introspection and forbidden to schema authors. Federation is a layer implemented as ordinary schema members, so it takes one underscore, gaining a visual marker and no special status — which is exactly why `_entities` is an ordinary, callable, introspectable field of `Query`.
- Would a GraphQL server accept a schema defining a field called __entities?It should not. The specification reserves the two-underscore prefix for introspection and forbids type-system authors from using it, so a conforming library rejects the schema or fails its validation rules. The reservation exists so later editions can add meta-fields without colliding with names a user schema already took.
- Does _entities show up when you introspect a subgraph?Yes, as an ordinary field of `Query`, with its `representations` argument and its `[_Entity]!` return type, and an explorer will list it in the docs beside the domain fields. That is the practical difference from `__schema` and `__typename`, which the engine supplies and introspection does not list among a type's fields.
A double underscore is a reserved parking bay the standards body painted for itself; a single underscore is a hand-written 'staff' sign someone taped to an ordinary space.
saying these in an interview costs you the question
- Thinks the single underscore grants special treatment
- Believes __ names are merely a style convention
- Says _entities is hidden from introspection
- Assumes federation fields are part of the GraphQL specification
- Expects the name alone to keep _entities private