advanced

GraphQL schema and operations

Model types, fields, queries, mutations, subscriptions, nullability, input types, and operation contracts deliberately.

GraphQL exposes a typed schema clients query with a single endpoint. Operations: **Query** (read), **Mutation** (write), **Subscription** (push).

					type Order {
  id: ID!
  status: OrderStatus!
  total: Money!
  customer: Customer!
}

enum OrderStatus { PENDING SHIPPED CANCELLED }

input CreateOrderInput {
  customerId: ID!
  lineItems: [LineItemInput!]!
}

type Mutation {
  createOrder(input: CreateOrderInput!): CreateOrderPayload!
}

type Query {
  order(id: ID!): Order
  orders(first: Int!, after: String): OrderConnection!
}
				

Design choices:

  • **Nullability**: `!` only when the server always resolves; nullable for partial failures in lists.
  • **Input types** separate from output types; avoid exposing internal storage shapes.
  • **Connections** (Relay-style) for pagination: `edges { node cursor }`, `pageInfo`.
  • **Payload types** for mutations: `{ order, errors }` or union results for domain failures.

On interviews: when GraphQL beats REST (flexible reads, mobile clients), cost of unbounded queries, and schema evolution (deprecated fields, @oneOf).

Common pitfalls: mirror of database tables in the graph, everything non-null, mutations that look like RPC with no input validation, and breaking clients by removing fields without deprecation.

The trade-off is client flexibility versus server predictability — enforce complexity limits and persisted operations in production.

Checklist:

  • Model domain types, not tables.
  • Deliberate nullability and pagination patterns.
  • Deprecate before remove; additive schema changes.
  • Validate inputs at the API boundary.