Pattern Adoption Stories from Readers: Dutch Government & Energy Sector (5/5)

On pages like this, we collect contributions from readers of our patterns.

Part 4 Resources

This pattern adoption story was contributed by Ton Donker, Ruben Haasjes and their readers group. It covers the 21 patterns presented as API Design Pattern of the Week on LinkedIn and Medium as well as other patterns from our book. This page features part 5 of 5 (part 1, part 2, part 3, part 4).

Frontend Integration

Known Uses

The Frontend Integration pattern is widely used in public APIs in both the government and energy domains. To mention a few examples:

  • Energieopwek.nl frontend: A public dashboard displaying near real-time data on sustainable energy production in the Netherlands.
  • Eancodeboek: A web-based search interface for looking up EAN connection identification codes for electricity and gas network connections in the Netherlands.
  • CBS StatLine Energy Datasets: The Dutch Central Bureau of Statistics (CBS) offers open data APIs, such as the one detailing the supply, transformation, and consumption of energy in a balance sheet format.

These APIs expose Information Holder Resources in Public APIs for Frontend Integration or Backend Integration.

Discussion Input

It is often debated whether frontend and backend should be separate bounded contexts; however, DDD defines bounded contexts by business – not technical – boundaries. Consequently, frontend and backend typically share the same context, ubiquitous language, and domain model. You should only split them when they embody different domain models or are owned by separate teams with distinct responsibilities. As a rule of thumb, if both layers use the same precise business language, they belong to a single bounded context; otherwise, distinct contexts make sense. Separation must be driven by domain considerations, not by the fact that one part runs in React and the other in Spring Boot, Node.js, or any other technology. We believe this aligns with the Lakeside Mutual context map and its refinement into core service components, as described in the book in the Architecture Overview of the Lakeside Mutual case study (p. 35).

Front‑end Knowledge Base Dutch Government: Reflecting the Dutch government’s emphasis on user interface development and design consistency across digital services.

Backend Integration

Known Uses

The Backend Integration pattern is widely used in enterprise systems and is often distinguished from Frontend Integrations. It’s also known as horizontal integration or system‑to‑system integration.

Discussion Input

In many so‑called system‑to‑system integrations, systems merely exchange data. But when complex tasks – taking minutes or even hours and involving queues or human interventions – are distributed this way, you cannot wait for the job to complete. A standard synchronous RESTful HTTP (request/response) approach quickly encounters time‑outs and lacks scalability.

The Backend Integration pattern aligns with the Enterprise Integration Patterns (EIP) focus on messaging: asynchronous messaging delivers reliability, decoupling and resilience, and avoids blocking callers. Both queue‑based and publish/subscribe channels are widely used for backend integration, exposing APIs for message producers and consumers.

The book also implicitly demonstrates that the Backend Integration pattern enforces separation of concerns, keeping business logic distinct from integration responsibilities. API design matters for asynchronous message channels just as it matters for synchronous Web API calls.

Community API

Known Uses

This pattern is widely used in Dutch government and especially in the Dutch energy sector.

“Ketenpartners” (chain partners) in the energy sector include grid operators, suppliers, metering companies, service providers, and other market parties. These are distinct legal entities collaborating on shared processes and data exchange. This matches the definition of Community APIs, which are designed for a defined, closed group of external organizations rather than the general public. EDSN (Energy Data Services Netherlands) provides central platforms and governance for these APIs, ensuring all ‘ketenpartners’ have access to the same interfaces, documentation, and support. This is a hallmark of Community APIs, where access is managed and the API is not public but available to all approved community members. The way ketenpartners operate via EDSN’s platforms is a practical example of the Community API pattern in action.

Discussion Input

  • Although both Community APIs and Partner APIs restrict access to a closed group and enforce strong security, they refer to distinct concepts (we believe): Partner APIs are built for formal B2B relationships under explicit partnership agreements. Community APIs enable broader collaboration among organizations sharing a common domain or purpose; participants may include non‑commercial or semi‑commercial entities, not just formal partners.
  • On the pattern summary for Community API, the interfaces between bounded contexts in the backend are cited as examples of Community APIs. Depending on the user group and network zone that the API clients reside in, these interfaces could also be considered Public APIs, since they expose functionality outside their own context. For instance, the Customer Core context publishes an Open Host Service (OHS) that acts like a Public API.

Solution-Internal API

Known Uses

Patterns like the Solution‑Internal API and Backend Integration form the backbone of many enterprises’ integration landscapes and are standard practice in modern enterprise architectures.

Discussion Input

The book explains that Solution‑Internal APIs can sometimes evolve into Community APIs or even Public APIs (p. 51). This ties directly into Jeff Bezos’s fifth API mandate, ‘APIs must be externalizable’, which calls for designing every API from day one with external consumers in mind - planning that transition and embedding the necessary safeguards from the start. Introduced in 2002, this rule ensures that, even if an API is initially intended for internal use, it’s always built with the option to expose it to outside developers. While designing for eventual externalization can be valuable in many scenarios, making it a universal, non‑negotiable requirement can introduce unnecessary complexity, consume resources, and sometimes stifle innovation when it’s applied without regard to real business needs or technical constraints. Designing Solution-Internal APIs for hypothetical external consumers can lead to over-engineering – in our humble opinion.

The Bezos API Mandate: Amazon’s Manifesto For Externalization

State Creation Operation

Known Uses

The pattern of creating new state via API operations (typically using POST requests to create resources or events) is a standard and widely adopted practice in both the Dutch government and energy sector APIs. Examples:

  • The Notifications API in the context of Zaakgericht werken (case-oriented working) is a standardized service used by Dutch municipalities to automatically inform different software systems when something important happens in the case management process such as a new case being created, a status being updated, or a document being added. The Notifications API implements the state creation operation pattern by allowing systems to create (POST) new notification events on the notification router component. For example, when a new case is created or a status changes, the responsible component sends a POST request to the Notifications API with details about the event. A system sends a POST to /api/v1/notificaties with event details (like the type of action, affected case, and timestamp). This creates a new notification event in the notification router, making it available for other systems to receive and process.
  • The DSP (Digital Collaboration Platform) is a messaging platform that facilitates the exchange of standardized messages between Grid Operators and Contractors, following a defined process. The Grid Operator initiates this process by sending an assignment message to the Contractor via the Assignment API. Upon receiving a POST /opdracht request through this interface, the Contractor’s system creates the assignment. Subsequently, an assignmentId is returned as minimal feedback to confirm successful creation.
  • Behandeldienstconfiguratie beheren (Manage treatment service configuration) API: A RESTful HTTP API for managing treatment service configurations. It allows an administrative body to link an activity, for which it is the competent authority, to a treatment service. This API allows the creation of new configurations or associations and includes endpoints where clients can POST new configuration data – a State Creation Operation.
  • Job Vacancy API: storing new job vacancies from the websites WerkenvoorNederland.nl and WerkenbijdeOverheid.nl. The API allows for the creation (opslaan) of new job vacancies. This is a classic example of a State Creation Operation: the client submits a new job posting, which is then stored server-side.

Discussion Input

It’s worth noting that the Command Message (EIP) aligns with the State Transition Operation pattern (see link), not the State Creation Operation. In Domain-Driven Design (DDD) and CQRS, a command expresses an intention to change system state – that change might create new entities or update existing ones. In that sense, “state creation” is simply a special case of “state change.”

By contrast, events are best viewed as variants of State Creation Operations: they append new facts or entities to the system without ever reading or modifying what’s already there. In an event-sourced system, these append-only records denote “what has happened,” whereas the actual state transitions are driven by commands.

An interesting observation is to view commands, events, and state from a time perspective:

  • Commands capture user intent (a desired future state)
  • Event record decisions that have already occurred (the past)
  • State reflects the current snapshot of data at a given moment (the present)

See this LinkedIn post and this summary of Alex Lawrence’s talk “Messaging 101: The Basics of Message-Driven Systems”, which also has an additional EIP Mapping.

The book outlines various types of events, such as notifications, full reports, and delta reports. As Event-Driven Architecture (EDA) continues to gain momentum in our domains, it’s worth noting that – to the best of our knowledge – bulk or batch event processing (referred to as “bulk reports”) has not yet been adopted in our systems. For an overview of event types, see: Event Typology.

Computation Function

Known Uses

The Computation Function pattern is not widely used in the public domain, but there are several validation services available:

  • Geovalidation service: The Geovalidation service of the Dutch Cadastre (Kadaster) provides the capability to validate geometric data (such as areas of operation or locations) based on GML 3.2.2 SF2 (GML 3.2.2 Simple Feature profile level 2). The Geovalidation service generates a Validation Report, that can be retrieved or sent via a callback.
  • The Daisycon Energy API allows clients to submit customer-specific data, such as address and expected energy usage, to receive tailored energy pricing information. By processing these inputs to compute personalized offers, this API demonstrates the Computation Function pattern in practice.
  • Many linters are exposed as API endpoints (for example, you send code to /lint and receive a report). This is a classic example of the Computation Function pattern in practice. The API Design Rules Linter of the Dutch government is available both as an OAS Checker endpoint and via a command-line API Design Rules Validator interface. The ADR validator can be integrated into the Continuous Integration (CI) pipeline to automatically validate your API each time it is deployed.

Discussion Input

  • The Geovalidation service also offers a health check operation (GET /health). See also the Essent and Energiedirect API. Note, however, that since there is no input involved, this check operation is not strictly an example of the Computation Function.
  • The Computation Function pattern is very often implemented via a controller aka Processing Resource, like /calculate or /validate endpoints provided by the API implementation.
  • Validation functionality is often implemented upfront in an API. API providers should always perform validation prior to processing and explicitly state in the API contract that invalid input may be rejected (we believe).

Operational Data Holder

Known Uses

  • In the Dutch energy sector, APIs that deal with operational data are almost always internal (Solution-Internal APIs) or restricted to authorized partners (Community APIs). Examples:
    • Grid-connection management portals (DSO back-office systems)
    • Meter-reading submission APIs used by certified measurers
    • Outage-management interfaces for field technicians
    They handle highly operational data like meter readings, switching events, connection request; data that is short-lived, constantly changing, and essential to daily energy market operations. As such, they follow the Operational Data Holder pattern.
  • Energieonderbrekingen.nl is a collaborative platform developed by the Dutch grid operators Enexis Netbeheer, Liander, and Stedin. It provides real-time information about electricity and gas outages across the Netherlands, offering an up-to-date overview of current disruptions in the energy network. The platform also offers a Disruptions API for developers to access outage data programmatically. Energy outages are operational data: they’re short-lived, frequently updated, and linked to multiple entities like locations, customers, and equipment.
  • Job Vacancy API: Counting, retrieving, filtering, and storing new vacancies - provide the full CRUD surface that typifies the Operational Data Holder pattern. Job vacancies are operational data (short-lived and frequently updated).
  • Behandeldienstconfiguratie beheren (Manage treatment service configuration) API: A RESTful HTTP API for managing treatment service configurations. It allows an administrative body to link an activity, for which it is the competent authority, to a treatment service. Allows authorities to create and update configuration mappings for ‘behandeldiensten’. These configurations change frequently and must be managed via CRUD.

Discussion Input

Two key takeaways we identified:

  • Practical modeling of dynamic business data: The Operational Data Holder (ODH) pattern offers a clear, actionable approach for modeling and exposing fast-changing business data through APIs. It highlights the importance of operational resilience and domain-specific extensions (p.185) – aspects often neglected in generic CRUD-based APIs (we believe).
  • Enhancing business alignment in microservices: Business alignment is a core principle in microservices architecture. Services should be organized around specific business capabilities to ensure they support concrete functions or value streams. In this context, the ODH pattern primarily acts as a marker pattern in API documentation, helping to align technical interfaces more closely with business concerns (p.188).

We found it helpful that the book clarifies that OPH, MDH, and RDH are all specializations of the Information Holder Resource. They differ in terms of mutability, relationships, and instance lifetimes, collectively forming a distinct category.

Master Data Holder

Known Uses

The Master Data Holder pattern is frequently used in APIs within both the Dutch government and the Dutch energy sector domains. These sectors often expose long-lived, high-quality reference data, such as registers, addresses, and energy connection points – through dedicated API endpoints, following the principles of the Master Data Holder pattern to ensure data consistency and accessibility across organizations. Examples:

  • KVK Handelsregister suite (Chamber of Commerce Business Register Suite). Several KVK APIs serve as authoritative company master-data holders:

These endpoints provide the canonical company information (legal name, RSIN, addresses, ownership, activity codes) which:

  • Changes infrequently (company details seldom change day-to-day)

  • Is consumed by many downstream services (credit checks, regulatory reporting, public directories)

  • Exposes all retrieval operations needed for consumers of master data

  • The OData API of the Dutch House of Representatives (Tweede Kamer) – exemplifies the Master Data Holder pattern by offering consistent, authoritative access to core parliamentary data such as members and party information. The API is read-only, with no public write or delete operations, reflecting standard practice for open government data. It serves as a reliable source for external systems, researchers, and the public, supporting transparency and trust in official information.

  • EDSN (Energy Data Services Netherlands) plays a vital role in the Dutch energy sector by maintaining official registers that serve as trusted sources of master data. These registers – examples of the Master Data Holder pattern – are made available to key market participants, including suppliers, grid operators, and metering companies, through Community APIs. This shared access helps support their daily operations and ensures reliable, high-quality data exchange across the entire energy sector. To mention a few registers:

    • CAR: Central Connections Register – central register with data of all electricity and gas connections in the Netherlands
    • CERES: The is the central registration system for energy-producing and energy-consuming installations
    • CPR: The register of market participants’ contact persons

Discussion Input

The book covers several design implications of the Master Data Holder Pattern, and we found them really insightful. Here’s our take on it:

  • One-way references: Master data gets referenced by operational data, but not the other way around. This helps avoid circular dependencies and keeps things clean.
  • Delete handling: Instead of actually deleting records, they’re often just marked as inactive – for compliance, audit trails, and to avoid accidental data loss.
  • When to use It: This pattern works well when the data is stable, heavily used by other parts of the system, and needs to be accurate and well-protected.
  • Change impact: Be extra careful with updates and deletions since master data is widely referenced, changes can have a big ripple effect.
  • Data quality and protection: Master data needs strong validation, access control, and audit logs. It is the kind of data you really want to get right.
  • Centralized Management: Master Data Holders often act as the go-to source of truth. That’s great for consistency and governance, but you’ll need to think about how to scale and keep them available.
  • Extensibility: The pattern also leaves room for things like bulk updates, archiving, or time-based queries depending on your domain’s needs.

Reference Data Holder

Known Uses

This pattern is frequently used within both the Dutch government and the Dutch energy sector domains. Examples:

  • ‘Mijn Aansluiting’ offers an online platform facilitating communication between contractors, grid operators, and energy suppliers regarding the administration and maintenance of energy connection points. The platform’s APIs provide access to reference data such as connection types and statuses, adhering to the Reference Data Holder pattern. These APIs are documented and accessible via the DSP Platform Wiki. See the ‘status’ field as example of reference data in the CAPO API (CAPO = Combi Aansluiting Proces Ondersteuning = Combined Connection Process Support) API;

  • CBS Content Open Data (OData API): Provides access to all Dutch statistics from CBS (Statistics Netherlands) via OData v4. Many of the datasets (e.g., country codes, region codes, statistical classifications) are reference data: they change rarely, are centrally managed, and are consumed by many systems.

  • PDOK Locatieserver (Geocoding, Address, Zip Code, and Place Lookup). PDOK stands for Publieke Dienstverlening Op de Kaart (PDOK), which means public services on the map. This RESTful API allows searching addresses, zip codes, cadastral parcels, municipalities, neighborhoods, and more. It supports autocomplete, reverse geocoding, and direct lookup by text or code.

  • RFC 9457 is the standard for error handling in both our domains, and it includes a type field which serves as a reference endpoint.

    Example: "type": "https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#/10.4.1"

    The type field in the error payload acts as a Reference Data Holder, using a URI to identify a specific error type or validation rule. This follows best practices for reference data, where values are not arbitrary but instead link to authoritative definitions or controlled vocabularies.

Discussion Input

We see reference data as a subset or a foundation of master data, providing structure and classification, while master data contains the business-critical entities that evolve over time.

In the energy sector, we use a structured approach to identify the functional source of a given identifier (MRID). Each MRID includes an additional attribute called identificationScheme, which classifies the identifier using a URI. By leveraging the identificationScheme and a conversion API, it’s also possible to reclassify an MRID. This allows, for example, retrieval of related resource information from another system – where the same resource might be represented by a different MRID.

Example of an EAN MRID classification:

"MRID": {
  "content": "871687110001427844",
  "_identificationScheme": "urn:x-enexis:ecdm:schemes:mrid:connections:ap:e"
}

Both the MRID and Error 9457 type field examples demonstrate a powerful design approach that combines two architectural patterns:

This combination improves consistency, clarity, and interoperability. It ensures that all parties interpret identifiers and errors the same way, using shared vocabularies and references, while adding meaningful context without overwhelming the payload.

Known Uses

The Link Lookup Resource pattern is a specialized API endpoint, sometimes known as an API Directory, Endpoint Repository, or Service Registry, that lets clients retrieve the current URIs of all available API endpoints. At present, government and energy-sector APIs do not use this pattern. Instead, most APIs provide resource collections (such as /zaken, /adressen, or /subsidieregelingen) and include links to related resources directly within each response. This means clients are expected to follow these embedded hyperlinks, rather than querying a separate link lookup endpoint. As a result, there are no dedicated link lookup resources in individual APIs for dynamically discovering up-to-date endpoint addresses. The only exception is the API gateway portal, which acts as a central registry of available APIs – but it does not offer per-service lookup endpoints.

Wish Template

Known Uses

The Wish Template is a design pattern that lets API clients specify exactly which nested data structures they want returned. By mirroring the desired response shape in the request itself, it leverages the mechanics of graph‑style APIs, allowing clients to traverse and select interconnected data. As noted in the book, GraphQL is concrete realization of this pattern.

GraphQL is used sporadically within the Dutch government and not in the Dutch energy sector.

Example from Dutch government: The Term Network is an API for searching terms across common thesauri, classification systems, and reference lists provided by the Dutch government. It offers even a GraphQL playground. This example highlights that the Wish Template design pattern and its GraphQL realization are a good fit for complex or frequently changing frontend needs; however, they can also lead to overengineering situations.

Discussion Input

Comparing the Wish Template and Wish List pattern usually kicks off chats about where they work best and how to actually put them into practice. OData allows you to apply query options not only at the top level but nested within $expand and even inside $select. So you can refine, filter, order or limit the very entities you’re expanding without pulling back every property or related record. GraphQL queries are inherently hierarchical: clients define the exact shape of the response through nested selection sets rather than separate $select or $expand options as in OData. So, we think the Wish List aligns with OData, while the Wish pattern aligns with GraphQL. OData uses URL query parameters for its Wish list (e.g., $filter$select$expand), whereas GraphQL operations are sent primarily as a request payload following the Wish Template. As stated in the book: GraphQL can be seen as a large-scale framework realization of the Wish Template pattern.