Examples
Every runnable example in this repo, mapped to the chapter it supports.
Every hands-on chapter in this site has a matching runnable example under
examples/
in the repo. Each hands-on example ships both a Quarkus (SmallRye GraphQL) and a
Python (Strawberry) implementation, built code-first against the same canonical SDL,
and a verify.sh that calls the running services, asserts response semantics as well as status codes,
and checks each stack’s live schema against the contract.
| Example | What it shows | Stacks | Chapter |
|---|---|---|---|
| 00-prerequisites | Lab skeleton — both stacks serve a canned cargo(trackingId:) slice, reject bad scalars, and conform to the canonical SDL |
Both | Ch0 |
| 03-sdl-type-system | Type system — enums, Node dispatch by id, DateTime and custom scalars, identical values on both stacks |
Both | Ch3 |
| 04-nullability | Null propagation — a failed voyage nulls at the leg, a null loadLocation bubbles to itinerary, a failed delivery nulls cargo; error paths asserted exactly |
Both | Ch4 |
| 05-contract-first | Contract-first — SDL exported from both stacks, a two-direction drift gate, five seeded drifts that fail it | Both | Ch5 |
| 06-execution-model | Execution phases — zero source calls on request errors, sibling resolvers overlapping in time, operationName selection |
Both | Ch6 |
| 07-queries-resolvers | Resolver chain — parent values keying child calls, a derived Delivery, @include/@skip pruning source calls |
Both | Ch7 |
| 08-mutations | registerHandlingEvent — coercion errors vs userErrors, payload re-read, serial aliased mutations, idempotent replay under parallel retries |
Both | Ch8 |
| 09-error-handling | Exposed vs masked execution errors — partial data with error paths, a stable extensions.code vocabulary, internal detail kept in the server log, status codes by media type |
Both | Ch9 |
| 10-schema-design | Node refetch rule, nodes(ids:) order and null semantics, naming and payload conventions checked against both live schemas |
Both | Ch10 |
| 11-evolution | finalArrivalDate deprecated for finalArrivalTime on both stacks, and the breaking-change gate run on safe, dangerous, breaking and strict-mode fixtures |
Both | Ch11 |
| 12-pagination | Relay connections with opaque keyset cursors — forward and backward paging, stability under inserts, the edge-node fuse, and the 29-call N+1 baseline | Both | Ch12 |
| 13-dataloaders | N+1 measured and batched — SmallRye @Source List batch resolvers and Strawberry DataLoaders, 29 source calls down to 8 (Quarkus) and 6 (Python) |
Both | Ch13 |
| 14-query-cost | Depth, token, alias and list-aware cost limits on both stacks; deep, wide and batched requests are refused before any source call | Both | Ch14 |
| 15-persisted-queries | Apollo automatic persisted queries and a trusted-document allowlist, GET by hash, mutations kept on POST | Both | Ch15 |
| 16-caching | Cache-Control per response, an nginx edge cache (MISS, HIT, BYPASS), field caches with expiry and invalidation on write |
Both | Ch16 |
| 17-transport-security | TLS with certificates generated at run time, public and internal instances, introspection off in public, CORS and JSON-only request bodies | Both | Ch17 |
| 18-authn-authz | Keycloak-issued JWTs, operation- and field-level authorization, a shipper sees only its own cargos on every path | Both | Ch18 |
| 19-observability | A trace per request joined to the caller’s trace id, a span per resolver, span metrics, errors by code, deprecated-field usage by client, and the error log line found by trace id | Both | Ch19 |
| 20-federation | Four subgraphs (cargo and handling on both stacks), explicit composition with The Guild’s composer, two cross-wired Hive Gateways, the query plan counted per subgraph | Both | Ch20 |
| 21-real-time | Subscription.cargoHandled over graphql-transport-ws on both stacks, GraphQL over SSE on Python, a plain SSE feed that resumes from Last-Event-ID, every subscriber cleaned up |
Both | Ch21 |
| 22-client-integration | Apollo Client’s normalized cache with typed documents from codegen, Python gql validating against the schema, the SmallRye typesafe client reading a partial page |
Both | Ch22 |
| 23-testing | Six test layers on both stacks in UBI test images (schema, resolver unit, operation, contract, client documents, load); k6 load runs assert per-request call shapes, refusals with no call, and one write under concurrent retries | Both | Ch23 |
| 24-debugging | A seeded fault diagnosed from the error path and from extensions.traceId through Tempo and Loki; a debug log category switched at run time; GraphiQL and the Dev UI on dev instances only |
Both | Ch24 |
| 25-docker-compose | Both stacks behind an nginx edge (TLS 1.3, a 64k body limit, only /graphql routed) on an internal network, with configs, secrets, health, limits, restart and graceful stop |
Both | Ch25 |
| 26-minikube | One Helm chart for both stacks on minikube: probes, ConfigMaps, generated TLS, NetworkPolicy and helm test, behind a NodePort edge (cluster tier, no verify.sh) |
Both | Ch26 |
| 27-final-project | Every defence together: the complete schema with subscriptions, cost limits, Keycloak authorization on every path, internal-only introspection and k6 through the edge, on Compose and on minikube | Both | Ch27 |
| 99-appendix-a-openshift-crc | The final project’s chart on OpenShift Local through a wrapper chart: Routes, in-cluster builds and ImageStreams (cluster tier, validated statically) | Both | Appendix A |
Running an example
Each directory is self-contained — a README.md, a compose.yaml, and a
verify.sh that calls the running services, asserts response semantics as well
as status codes, and checks each stack’s live schema against the canonical SDL
under contracts/schema/. The cluster-tier examples ship a helm/ chart
instead and run on minikube or CRC.
cd examples/05-contract-first
./verify.sh
See Prerequisites & the Lab for the full toolchain setup.