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