Consider the following coarse grained REST apis for a Contact resource
POST /api/contacts
GET /api/contacts
GET /api/contacts/:id
PUT /api/contacts/:id
DELETE /api/contacts/:id
Consider using eventsourcing for the contact resource, i.e. commands are validated and events are stored. So every event must be stored, including each field level change.
CreateContactCommand -> | Contact("john", "doe", 25) | -> ContactCreatedEvent
FirstNameChangeCommand -> | Contact("jane", "doe", 25) | -> FirstNameChangedEvent
LastNameChangeCommand -> | Contact("jane", "dear", 25) | -> LastNameChangedEvent
AgeChangeCommand -> | Contact("jane", "doe", 30) | -> AgeChangedEvent
Now, combining REST and EventSourcing both.
Doing REST, how the client communicates to the above standard REST APIs for field level changes to generate commands at server side REST end point?
Major question is, how to design REST API so that it can also support the commands eventually supporting eventsourcing?
If anybody could shed light on this, the help would be greatly appreciated.
CQRS and event Sourcing is neither an API design principle, nor is it a top-level architecture. Still, if you want to 'expose' your API as a task-based API, you can expose links as part of the contact resource.
GET /contacts/1234
Response
200 OK
<contact>
<atom:link href="/contacts/1234/first-name" rel="first-name" />
<atom:link href="/contacts/1234/last-name" rel="last-name" />
<atom:link href="/contacts/1234/age" rel="age" />
<first-name>Jane</first-name>
<last-name>Doe</last-name>
<age>25</age>
</contact>
The assumption here is that you change the API to a true level 3 REST API.
Also, /contacts/1234
will only accept GET
and DELETE
(not PUT
) requests. If a client wants to change e.g. the first name of a contact, it must follow a link with the relationship type first-name
and make a PUT
request against that resource:
PUT /contacts/1234/first-name
<first-name>John</first-name>
Anything else than a first-name
field PUT
here should be ignored or rejected.
Thus, when the service receives a PUT
against a first-name resource, it's a command to change the first name of the contact.
This still isn't a proper task-based API because it doesn't capture why the first name changes, but I hope you get the idea.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With