Pattern Sections
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:
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 ofattendees
that are identified by their email addresses, but also have atype
and astatus
.
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
Note that this is (almost) the same context as in the sibling pattern Linked Information Holder.↩︎