Appendix A

Endpoint Identification and Pattern Selection Guides

This appendix provides guidance on when to apply which pattern in the form of a cheat sheet. It also connects our pattern language with responsibility-driven design (RDD), domain-driven design (DDD), and the Align-Define-Design-Refine (ADDR) process.

Cheat Sheet for Pattern Selection

The cheat sheet provides issue-pattern tables to indicate when a particular pattern is eligible. Please note that this is a gross simplification of a set of complex design problems and considerations. The decision models in Part 1 and the pattern texts in Part 2 discuss context, forces, and consequences of related solutions in much more depth. Chapter 4 provides several more entry points for book content and pattern language.

Getting Started with API Design

Foundation patterns address the early and basic API scoping issues. Table A.1 lists such issues and corresponding patterns.

The selection of these patterns is driven by criteria such as type of client, business model, product/project vision, and project/product context. The client portfolio (that is, number and location of clients, information needs of these clients), and security requirements are important criteria to consider. Chapters 1, 3, and 4 collect many more decision drivers and desired qualities.

Table A.1 Eligibility of API Foundation Patterns (Covered in Chapter 4)

Issue

Patterns to Consider

An end-user application wants data from or activity in a backend

Realize a FRONTEND INTEGRATION API

Two backends have to collaborate to fulfill a business requirement

Realize a BACKEND INTEGRATION API

A new API should be broadly accessible

Introduce a PUBLIC API

The visibility of a new API should be restricted to a group of clients

Introduce a COMMUNITY API

A new API targets a single application only, for instance to decompose it into services

Introduce a SOLUTION-INTERNAL API

Next up, in Table A.2, responsibility patterns can jumpstart API endpoint design.

Table A.2 How to Identify and Classify API Endpoints by Role (from Chapter 5)

Issue

Pattern(s)

Identify API endpoint candidates

Apply DDD and/or stepwise API design practice such as ADDR or one of those compiled in Design Practice Reference [Zimmermann 2021b]

Model a business capability that is action-oriented (representing business activities or commands)

Define a PROCESSING RESOURCE and realize the required activities as well as coordination and state management in its operations (see Table A.3)

Model a business capability that is data-oriented

Define an INFORMATION HOLDER RESOURCE, being aware of the coupling introduced and provide suited create, read, update, delete, and search operations for it (Table A.3)

Let applications exchange transient data without coupling them directly

Define a DATA TRANSFER RESOURCE and add API clients to the applications

Decouple provider locations from clients

Provide a LINK LOOKUP RESOURCE as an directory serving dynamic endpoint references

Expose short-lived, transactional data

Mark an INFORMATION HOLDER RESOURCE as OPERATIONAL DATA HOLDER

Expose long-lived, mutable data

Mark an INFORMATION HOLDER RESOURCE as MASTER DATA HOLDER

Expose long-lived data not mutable for clients

Mark an INFORMATION HOLDER RESOURCE as REFERENCE DATA HOLDER

During endpoint identification, one might decide to define one API or one API endpoint for each “Bounded Context” from DDD if logic and data are highly cohesive [Singjai 2021a]. If fine-grained decomposition is desired and possible, “Aggregate” may initiate API and API endpoint identification [Singjai 2021b; Singjai 2021c].

The operations exposed by API endpoints differ in the way they touch (or do not touch) provider-side state: read, write, read-write, or neither read nor write (Table A.3).

Table A.3 How to Classify Operations (from Chapter 5)

Issue

Pattern(s)

Allow API client to initialize provider-side state (including domain-layer entities)

Mark an operation as write-only STATE CREATION OPERATION

Allow API client to query and read provider-side state

Mark an operation as read-only RETRIEVAL OPERATION

Allow API client to update or delete provider-side state

Mark an operation as read-write STATE TRANSITION OPERATION (variants: full/partial state replacement, state deletion)

Allow API client to invoke a state-agnostic operation

Mark an operation as COMPUTATION FUNCTION

Designing Request and Response Message Structures

Once the roles and responsibilities of API endpoints and their operations have been characterized, it is time to specify the data contract (the structure of headers and body in request and response messages, that is). Table A.4 shows the different options.

Table A.4 Basic Message Structure Patterns (from Chapter 4)

Issue

Pattern(s)

Data is simple

Design ATOMIC PARAMETER and/or ATOMIC PARAMETER LIST for request and response messages

Data is complex

Design PARAMETER TREE, possibly arranged as PARAMETER FOREST for requests and responses; PARAMETER TREES may contain others and ATOMIC PARAMETERS or ATOMIC PARAMETER LISTS as leaves

Table A.5 shows how, in message payload design, both basic and structured message elements may receive certain stereotypical roles.

Table A.5 Element Stereotypes (from Chapter 6)

Issue

Pattern(s)

Exchange structured data (for instance, domain entity representations)

Add DATA ELEMENT with EMBEDDED ENTITIES to message payload (following entity relationships)

Distinguish representation elements or other API parts

Add ID ELEMENT to message payload (locally or globally unique)

Make operation flow flexible

Upgrade from ID ELEMENT to LINK ELEMENT to support the REST principle of hypertext as the engine of application state (hypermedia controls); links may refer to PROCESSING RESOURCES or INFORMATION HOLDER RESOURCES

Annotate payload to ease processing

Add METADATA ELEMENTS (control, provenance, aggregated metadata)

Improving API Quality

Patterns related to API quality can help solve interoperability issues and size message representations right if the goal is to achieve data transfer parsimony (Table A.6).

Table A.6 When to Apply Which Quality Improvement (from Chapters 6, 7, and 9)

Issue

Pattern(s)

API clients report interoperability and usability problems

Switch from minimal to elaborate API DESCRIPTION

Add METADATA ELEMENTS to PARAMETER TREES

Introduce a CONTEXT REPRESENTATION in the payload encapsulating control metadata such as quality-of-service properties

API usage mistakes and other faults are difficult to analyze and fix

Add an ERROR REPORT to response representations to describe failures in detail

API clients report performance problems

Switch from EMBEDDED ENTITIES to LINKED INFORMATION HOLDERS to adjust message size and service granularity (the two patterns can be combined flexibly)

Reduce the amount of transferred data with a WISH LIST or a WISH TEMPLATE

Consider other quality patterns improving data transfer parsimony (for instance, CONDITIONAL REQUEST or REQUEST BUNDLE)

Introduce PAGINATION

Access control is needed

Introduce API KEYS or more advanced security solutions

API Support and Maintenance

API providers have to deal with change and must balance compatibility and extensibility. The evolution patterns in Table A.7 cover strategies and tactics for doing so.

Table A.7 When to Apply Which Evolution Pattern (from Chapter 8)

Issue

Pattern(s)

Indicate changes that are not backward compatible

Introduce a new major API version with a new, explicit VERSION IDENTIFIER

Communicate the impact and significance of changes from version to version

Apply SEMANTIC VERSIONING to distinguish major, minor, and patch versions

Maintain several versions of API endpoints and their operations

Offer TWO IN PRODUCTION (variant: N IN PRODUCTION)

Avoid having to support multiple versions of API endpoints and their parts (including message structure elements)

Announce an AGGRESSIVE OBSOLESCENCE strategy and announce a decommissioning/removal date at any time (but grant an intermediate deprecation period)

Commit to keeping API available and supported for a fixed amount of time

Give a LIMITED LIFETIME GUARANTEE and communicate it at API publication time

Avoid committing to stability and future existence of API

Position API as an EXPERIMENTAL PREVIEW

API Release and Productization

Once an API goes into production, documentation and governance tasks come into play. Table A.8 introduces some common issues and applicable patterns.

Table A.8 API Specification and Documentation (from Chapter 9)

Issue

Pattern(s)

Clients need to know how to call the API

Create and publish a minimal or elaborate API DESCRIPTION

Ensure fair use of the API

Enforce a RATE LIMIT

Charge for API usage

Establish a PRICING PLAN

Communicate quality-of-service characteristics

Issue a SERVICE LEVEL AGREEMENT or informal specification

“Driven” API Design

This section provides background information on RDD, summarizes how to leverage DDD to craft APIs, and revisits the complementary nature of the ADDR process (introduced at the beginning of Part 2) and our patterns.

RDD Concepts

To order and structure the endpoint and operation design space (or, in ADDR, the Define phase), we adopt some of the terminology and the role stereotypes from RDD [Wirfs-Brock 2002]. RDD was originally created for the context of object-oriented analysis and design (OOAD), which becomes apparent in its core definitions:

  • An application is a set of interacting objects.

  • An object is an implementation of one or more roles.

  • A role groups related responsibilities.

  • A responsibility is an obligation to perform a task or know information.

  • A collaboration may be an interaction of objects or roles, or a combination of both.

  • A contract is an agreement outlining the terms of a collaboration.

In our experience, RDD works equally well on the code level and on the architecture level. As API design has both architectural and developmental ramifications, the role stereotypes in RDD are a natural choice to express API behavior. For instance, all API endpoints can be seen to have (remote) interfacers that provide and protect access to service providers, controllers/coordinators, and information holder roles. The read-write operations exposed by API endpoints correspond to responsibilities. The API DESCRIPTION specifies the RDD contract, and collaborations arise from calls to API operations.

The patterns in Chapter 5 pick up these terms and concepts for the context of API design.

DDD and API Design

DDD [Evans 2003; Vernon 2013] and our patterns are also related in several ways:

  • DDD “Services” are good candidates for remote API exposure.

  • A DDD “Bounded Context” may correspond to a single API (with several endpoints).

  • A DDD “Aggregate” can also be exposed via an API (possibly having several endpoints, starting with the root “Entity”). Depending on the nature of an Aggregate, a PROCESSING RESOURCE is often preferred over an INFORMATION HOLDER RESOURCE; see the discussions in these two patterns for rationale.

  • DDD “Repositories” deal with entity life-cycle management, which involves read and write access to API provider-side application state (as defined by our operation responsibility patterns). For instance, repositories usually provide lookup capabilities, which may turn into API-level RETRIEVAL OPERATIONS. Special-purpose repositories may yield LINK LOOKUP RESOURCES. DDD “Factories” also deal with life-cycle management and may donate additional API operations (unless their functionality should remain an API-implementation detail).

  • DDD “Value Objects” can be exposed as data transfer representations (DTRs) in the Published Language established by the data part of the API DESCRIPTION. DATA ELEMENT from Chapter 6 is a related pattern.

In DDD, the Aggregate and Entity patterns often expose process-like properties (as they represent groups of domain concepts that have an identity and a life cycle at runtime). Hence, these patterns can help identify STATE CREATION OPERATION and STATE TRANSITION OPERATION candidates during endpoint identification. However, it is important not to expose the entire domain model as Published Language on the API level because this creates an undesired tight coupling between the API clients and the provider-side API implementation.

DDD does not distinguish between master data and operational data in its tactic patterns; both operational data and master data may be part of the Published Language and appear in dedicated Bounded Contexts and Aggregates as Entities (see [Vernon 2013]). In DDD, domain event sourcing [Fowler 2006] is the recommended practice to integrate Aggregates (both within the same and in different Bounded Contexts) because it decouples them and allows replaying events up to the current state in case of failures that lead to consistency issues. APIs may support this.

In Principles of Web API Design, James Higginbotham reminds us that “resources are not data models” and “resources are not objects or domain models” [Higginbotham 2021], with resources corresponding to endpoints in our technology-neutral terminology. And “REST was never about CRUD” either. That said, data and domain models may still serve as API design input when taken with a grain of salt.

ADDR and Our Patterns

Principles of Web API Design [Higginbotham 2021] also is the source of the ADDR process that we roughly followed in Part 2.

Table A.9 summarizes the correspondences between ADDR phases/steps and the patterns from this book. It also provides application examples from our sample case (note that some of the pattern selection decisions appeared in the narratives in Chapter 3).

Table A.9 ADDR to Pattern Mapping (with Examples)

Phase/Step

Pattern(s)

Example

Align

1. Identify Digital Capabilities

Foundation patterns (Chapter 4)

User story about “contact information updates” in Chapter 2

2. Capture Activity Steps

n/a

The agile practice of story splitting could be applied; same for event storming (examples available online)*

Define

3. Identify API Boundaries

Foundation patterns (Chapter 4)

Lakeside Mutual domain model and context map in Chapter 2

Responsibility patterns (Chapter 5)

For example, PROCESSING RESOURCE, INFORMATION HOLDER RESOURCE USAGE IN LAKESIDE MUTUAL

4. Model API Profiles

Foundation patterns (Chapter 4)

See interludes in Chapter 3

Responsibility patterns (Chapter 5)

See interludes in Chapter 3

Initial SERVICE LEVEL AGREEMENT (Chapter 9)

See interludes in Chapter 3

Design

5. High-Level Design

Basic structure patterns (Chapter 4)

See interludes in Chapter 3

Element stereotype patterns (Chapter 6)

See interludes in Chapter 3

EMBEDDED ENTITY and LINKED INFORMATION HOLDER patterns (Chapter 7)

The HTTP resource APIs for Lakeside Mutual, implemented in Java, provide examples of pattern use (see Appendix B)

Technology realization of patterns (for instance, as HTTP resources)

See Appendix B

Refine

6. Refine the Design

Quality patterns (Chapters 6 and 7)

WISH LIST in operations of Customer Information Holder in Lakeside Mutual

7. Document the API

API DESCRIPTION, RATE LIMIT (Chapter 9)

See OpenAPI snippet in Appendix B for a minimal technical contract

Evolution patterns such as VERSION IDENTIFIER (Chapter 8)

See sample decisions in Chapter 3

* https://ozimmer.ch/categories/#Practices.

More details on the Identify API Boundaries step. Our messages are very much in line with James Higginbotham’s advice; for instance, our patterns help avoid the antipatterns he discusses [Higginbotham 2021, p. 70 ff.]. By considering our end-point role patterns from Chapter 5 when deciding between activity- or data-oriented semantics of endpoints and being aware of the differences in the responsibilities of their operations, antipatterns like the “Mega All-In-One API,” “Overloaded API,” and “Helper API” can be avoided.

More details on the Model API Profiles step. This is an ADDR step in which many of our patterns are eligible. For instance, the LINK ELEMENT pattern and related METADATA ELEMENTS from Chapter 6 may be used to describe the “resource taxonomies” (independent/dependent/associative resources) [Higginbotham 2021, p. 87], and the “operation safety classification” (safe/unsafe/idempotent operations) [p. 91] can be expressed with the operation responsibilities from Chapter 5.

More details on the High-Level Design step. This ADDR step is complementary to our Chapters 4, 5, and 7; the patterns from these chapters fit here. A RATE LIMIT (Chapter 9) can be part of the “API Management Layer.” Deciding whether to include related or nested resources, discussed in the context of “hypermedia serialization” [Higginbotham 2021, p. 127], is covered by our EMBEDDED ENTITY and LINKED INFORMATION HOLDER patterns. Our WISH TEMPLATE pattern provides complementary advice on “query-based APIs.”

More details on the Refine the Design step. Note that optimizing for performance on a platform-neutral level (as our Chapters 6 and 7 patterns do) is not covered as such in ADDR. That said, our Chapters 6 and 7 patterns belong to this phase and step in ADDR. Higginbotham’s process and our patterns complement each other here.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.157.105