Pattern: Embedded Entity

How can one avoid sending multiple messages when their receivers require insights about multiple related information elements?


The final version of this pattern is featured in our book Patterns for API Design: Simplifying Integration with Loosely Coupled Message Exchanges.

Pattern: Embedded Entity

a.k.a. Inlined Entity Data; Embedded Document (Nesting)

Context

The information required by a communication participant contains structured data. This data includes multiple elements that relate to each other in certain ways. For instance, a master data element such as a customer profile may contain other elements providing contact information including addresses and phone numbers, or a periodic business results report may aggregate source information such as monthly sales figures summarizing individual business transactions. API clients work with several of the related information elements when creating request messages or processing response messages. 1

Problem

How can one avoid sending multiple messages when their receivers require insights about multiple related information elements?

Forces

When deciding for or against this pattern, you have to consider its impact on:

  • Performance and scalability
  • Modifiability and Flexibility
  • Data quality
  • Data privacy
  • Data freshness and consistency

Traversing all relationships between information elements to include all possibly interesting data may require complex message representations and lead to large message sizes. It is unlikely and/or difficult to ensure that all recipients will require the same message content.

Pattern forces are explained in depth in the book.

Solution

For any data relationship that the client wants to follow, embed a Data Element in the request or response message that contains the data of the target end of the relationship. Place this Embedded Entity inside the representation of the source of the relationship.

Sketch

A solution sketch for this pattern from pre-book times is:

Figure 1: Sketch of Embedded Entity pattern (entities are represented as HTTP resources)

Example

Lakeside Mutual, a microservices sample application, contains a service called Customer Core that aggregates several information items (here: entities and value objects from Domain-Driven Design) in its operation signatures. An API client can access this data via an HTTP resource API. This API contains several instances of the pattern. Applying the Embedded Entity pattern, a response message might look as follows:

GET http://localhost:8080/customers/a51a-433f-979b-24e8f0

{
  "customer": {
    "id": "a51a-433f-979b-24e8f0"
  },
  "customerProfile": {
    "firstname": "Robbie",
    "lastname": "Davenhall",
    "birthday": "1961-08-11T23:00:00.000+0000",
    "currentAddress": {
      "streetAddress": "1 Dunning Trail",
      "postalCode": "9511",
      "city": "Banga"
    },
    "email": "rdavenhall0@example.com",
    "phoneNumber": "491 103 8336",
    "moveHistory": [{
      "streetAddress": "15 Briar Crest Center",
      "postalCode": "",
      "city": "Aeteke"
    }]
  },
  "customerInteractionLog": {
    "contactHistory": [],
    "classification": "??"
  }
}

The referenced information items are all fully contained in the response message (e.g., customerProfile, customerInteractionLog); no URIs (links) to other resources appear. Note that customerProfile actually embeds nested data (currentAddress, moveHistory), while the customerInteractionLog is empty in this exemplary data set.

Are you missing implementation hints? Our papers publications provide them (for selected patterns).

Consequences

  • An Embedded Entity reduces the number of calls required: If the required information is included, the client does not have to create a request to obtain it.
  • Embedding entities can lead to a reduction in the number of endpoints, because no dedicated endpoint to retrieve some information is required.
  • Embedding entities leads to larger response messages which take longer to transfer.
  • It can be difficult to anticipate what information different clients require to perform their tasks. As a result, there is a tendency to include more data than needed by (most) clients in an Embedded Entity, which leads to yet larger message sizes. Such design can be found in many Public APIs serving large and possibly unknown clients.
  • Large messages that contain unused data consume more bandwidth than necessary. However, if most or all of the data is actually used, sending many small messages might actually require more bandwidth than sending one large message (e.g., for header and metadata sent with the smaller messages multiple times).
  • If the embedded entities change with different speed (e.g., a fast-changing transactional entity refers to immutable master data), retransmitting all entities causes unnecessary overhead as messages with partially changed content cannot be cached. Consider switching to a Linked Information Holder (and maybe additionally apply the Conditional Request pattern for the linked entity).
  • Once included and exposed in an API Description, it is hard to remove an Embedded Entity in a backward-compatible manner (as clients may have begun to rely on it).

The resolution of pattern forces and other consequences are discussed in our book.

Known Uses

Many public APIs with complex response messages use the Embedded Entity pattern:

  • When retrieving an issue with the GitHub v3 API, the response also contains the full information about the milestone the issue is assigned to.
  • A tweet in the Twitter REST API contains the entire user information, including for example the number of followers the user has.
  • Many operations in the Microsoft Graph API apply this pattern. For instance, the user resource representations contain structured attributes that represent (sub-)entities (but also link to other resources via Linked Information Holders). For instance, the response body of List events contains an array of attendees that are identified by their email addresses, but also have a type and a status.

Plenty of APIs offered by custom enterprise information systems and master data management products also realize the pattern.

More Information

Related Patterns

Linked Information Holder describes a complementary solution for the reference management problem and can also be seen as an alternative (as explained above).

Wish List or Wish Template can help to fine-tune the content in an Embedded Entity, as explained above.

Operational Data Holders reference Master Data Holders by definition (either directly or indirectly); these references can either be represented as Linked Information Holders or flattened by using the Embedded Entity pattern. Similarly, Processing Resources might deal with structured data that needs to be linked or embedded; in particular, Retrieval Operations either embed or link related information.

Other Sources

See Section 7.5 in Sturgeon (2016) for additional advice and examples (“Embedded Document (Nesting)”).

References

Daigneau, Robert. 2011. Service Design Patterns: Fundamental Design Solutions for SOAP/WSDL and RESTful Web Services. Addison-Wesley.
Lübke, Daniel, Olaf Zimmermann, Mirko Stocker, Cesare Pautasso, and Uwe Zdun. 2019. “Interface Evolution Patterns - Balancing Compatibility and Extensibility Across Service Life Cycles.” In Proc. 24th European Conference on Pattern Languages of Programs (EuroPLoP), 15:1–24. https://doi.org/10.1145/3361149.3361164.
Sturgeon, Phil. 2016. Build APIs You Won’t Hate. LeanPub. https://leanpub.com/build-apis-you-wont-hate.


  1.  Note that this is (almost) the same context as in the sibling pattern Linked Information Holder.↩︎