-
Notifications
You must be signed in to change notification settings - Fork 0
Techniques for building hypermedia servers
Glenn Block edited this page Aug 7, 2014
·
20 revisions
Glenn Block
- Darrell Miller
- Mark Foster
- Jorn Wildt
When building a hypermedia system, you want to cleanly separate the business domain from what goes across the wire. This is important as it makes the code easier to maintain / extend and to test. To do this, you need a way to transition from the domain to an HTTP representation.
Here is a a pattern which is outlined in the [Designing Evolvable Web APIs] (http://chimera.labs.oreilly.com/books/1234000001708/ch07.html#_models_and_services) book.
- State model - An intermediary model that carries the data and links which will then be used to create a representation in a specific media type. Example [here] (https://github.com/webapibook/issuetracker/blob/BuildingTheApi/src/WebApiBook.IssueTrackerApi/Models/IssuesState.cs)
- State Factory - Given a domain model, it populates a State Model. The factory contains the state machine logic for building up the links. Example [here] (https://github.com/webapibook/issuetracker/blob/BuildingTheApi/src/WebApiBook.IssueTrackerApi/Infrastructure/IssueStateFactory.cs)
-
State model may have different interfaces / adapters for Mediatype Models i.e. models that contain data for a specific media type. For example the IssuesState model can generate CJ as it [implements] (https://github.com/webapibook/issuetracker/blob/BuildingTheApi/src/WebApiBook.IssueTrackerApi/Models/IssuesState.cs#L21) the
IReadDocument
[interface] (https://github.com/WebApiContrib/WebApiContrib.Formatting.CollectionJson/blob/master/src/WebApiContrib.CollectionJson/IReadDocument.cs) that the CollectionJson.NET library supports. - Serializer / Formatter - Responsible for taking a State Model or Mediatype Model and generating a representation from it. Example [here] (https://github.com/WebApiContrib/WebApiContrib.Formatting.CollectionJson/blob/master/src/WebApiContrib.Formatting.CollectionJson.Client/CollectionJsonFormatter.cs)
- Rather than using ACID transactions that block resources, it is better to think about using [Sagas] (http://www.cs.cornell.edu/andru/cs711/2002fa/reading/sagas.pdf) for long running processes which contain compensation actions that execute when the transaction fails. Also see this [article] (http://kellabyte.com/2012/05/30/clarifying-the-saga-pattern/) from [@kellabyte] (https://twitter.com/kellabyte) on the subject and this [talk] (http://www.infoq.com/presentations/Building-Reliable-Systems) (at around 18 minutes) from [@arnonrgo] (https://twitter.com/arnonrgo)
- Example: Consider a transaction consisting in withdrawal one item from inventory (-1). In a traditional ACID approach, we block inventory until the transaction is finished to maintain a consistent state. This however does not scale. Using a Saga, a compensating action would simple increment the inventory back by 1 if a failure occurs. This way the resources are freed up and no locks are held.
- The response of an asynchronous request could return an url where consult the progress state
- Push/Pull economy. Maybe using a bus architecture, and a pub/sub model
- Middleware to manage ETAGs / returning cached representations
- Expiration handled upstream per resource.
- Cacheable portions. Not everything must be invalidated at same time. Some portions can be updated.
- Cache based in multiple keys. Example: First key: Collection of books, Second key: Books published on July