CRUD APIs can be a very powerful tool. However, simply PUTing and POSTing entities can lead to anemic endpoints that lack business value. Go beyond the traditional CRUD API and provide more expressive and meaningful REST endpoints with an API crafted with a commanding paradigm.
Report
Share
Report
Share
1 of 40
Download to read offline
More Related Content
Cqrs api
1. Commanding a More
Meaningful REST API
Brandon Mueller
@fatmuemoo
fatmuemoo.com
2. Your API is Like a Town
● The town is a home to people, places and things. These
are the nouns in your API
● Nouns are also called resources or entities.
● The nouns are represented in your API by the URL.
● Like things inside of your town, you can do thing with
your resources.
● You tell your nouns to do things via verbs.
● The HTTP spec come with built in verbs, among these
are GET, PUT, POST, and DELETE
● These verbs are great for CRUD functionality.
3. HTTP verb Resource URL Explanation
POST Creates a street
GET Gets all the streets
in the town
GET Gets the street with
the ID of 11
PUT Updates the street
with the ID of 11
DELETE Deletes the street
with the ID of 11
C
R
UD
4. Some Good Ideas to Follow:
1. Use plural nouns
2. Nest resources!
3. Handle errors with a standardized response body
4. Use the standard HTTP verbs
5. Use appropriate HTTP headers
6. Use appropriate HTTP response codes
6. Idempotent/Safe Methods
Idempotent methods can be applied over and
over again and always have the same effect on
the resource
Safe methods do not have any modifying effect
on the resource
7. Idempotent/Safe Methods
Method Idempotent Safe
GET YES YES
POST NO NO
PUT YES NO
DELETE YES NO
PATCH NO NO
HEAD YES YES
OPTIONS YES YES
8. POST v PUT v PATCH
● POST is used to create an entity
● PUT is used to update an entity where you
must send the entire representation of the
entity as you wish for it to be stored
● PATCH is used to update an entity where
you send only the fields that need updated
9. Client
Client uses HTTP POST, GET, PUT and DELETE
Verbs to CREATE, READ, UPDATE and DELETE
Application Server
10. Create a Street
Server returns “201 created” status and a
JSON representation of the newly created
street, as well a link to the street
11. Read Streets
Server returns “200 OK”, and a JSON
representation of the streets
12. Update a Street
Server returns “200 OK” status and a
JSON representation of the street,
NOTE: Most implementations of the PUT verb require the entire representation of the entity.
See HTTP PATCH verb for updating with a partial representation of the entity.
13. Delete a Street
Server returns a ‘204 No Content’
status and should not have a
response body. Any further GET requests to /api/streets/30 should return a ‘404
Not Found’ status
14. Awesome!
● We can create some really awesome APIs
where we can create, read, update, and
delete entities in a standard way.
● These standards have lead to some very
powerful libraries that can help you create
and consume CRUD APIs
15. Where is the Business Logic?
Client
Client uses HTTP POST, GET, PUT and DELETE
Verbs to CREATE, READ, UPDATE and DELETE
Application Server
● Sometime this is what we want
● When we create APIs we don’t always know the specific
use case
● We just want to expose the data
16. Business Logic on The Client Side?
● A CRUD API is a really good way to expose
meaningful data in a flexible way
● You make few assumptions on how the data
will be displayed or used
● Fosters innovation and allows for really
interesting clients
17. Really? Client Side?
● Stopping at CRUD functionality limits what
your API can actually do
● Complex business problems should not rely
on client side implementations
● Only implementing CRUD functionality can
lead to an API that doesn't know what it
does, it only knows about the data it stores
18. Wait, This SUCKS!
How do you go beyond simply creating,
reading, updating, and deleting things?
● How do you repave a street?
● Condemn a house?
● Hospitalize a person?
19. Command API
Take a resources, add a command (verb) to the
end, send data for that command in POST
HTTP verb
○○○
20. Command or Resource?
Command Resource
Verb Noun
You can only POST and
sometimes GET never PUT or
DELETE
All HTTP verbs are OK
Once a command has been
submitted, it cannot be
removed or updated (read only)
Most resources can be
removed or updated
21. HTTP
Verb
Command URL Explained
POST Sends the command to repave
street 11
GET Meta data about repave
command and street 11.
Maybe the last time it was
repaved, whether or not we
are currently repaving
GET Meta data about the specific
instance of the repave
command
22. Example: Repave a street
Server response with ‘200 OK’ status, and meta
data about the command:
In this example, the command is executed and
completed within the lifecycle of the HTTP request.
23. Wait: That’s Not The Whole Story
We use a Commanding Pattern because we
are performing an action on a resource. In the
real word, these actions can take time.
24. Repave a Street
Server responds with ‘202 Accepted’
status, and meta data about the
command:
25. Repave a Street; Check Status
Server responds with ‘200 OK’ status and
data about the command
26. Client
Application Server
Client sends
POST command
Clients Checks
Status URL until
complete, updating
UI with progress
27. What About Querying?
● Sometimes a query request cannot be
completed in a reasonable amount of time
● Sometimes you have to send a POST
payload in order to send enough data for the
server to process a query
● This is a special case of a command
28. Querying
Just like a command, we return ‘202 Accepted’ status,
and return some meta data:
29. Getting Results...
If you try to hit the results link before the results are
complete:
● the server will return the search results in whatever
state is available
● return a ‘203 Non-Authoritative Information’
● a link to the status url
● and a Retry-After header
Using this pattern, you can expire content and return the
203 status code to tell the client to refresh the content
30. Getting Results...
HTTP Request
Do we have
the
resource?
203 With a Retry
After Header
And Status URL
200 OK
Has the data
expired or
still being
created?
Check
Status
Is it done?
Status
33. CQRS Martin Fowler
CQRS stands for Command Query Responsibility
Segregation. It's a pattern that I first heard described by
Greg Young. At its heart is a simple notion that you can use
a different model to update information than the model you
use to read information. This simple notion leads to some
profound consequences for the design of information
systems.
http://martinfowler.com/bliki/CQRS.html
34. DDD Wikipedia
Domain-driven design (DDD) is an approach to software
development for complex needs by connecting the
implementation to an evolving model. The premise of
domain-driven design is the following:
1. Placing the project's primary focus on the core domain
and domain logic.
2. Basing complex designs on a model of the domain.
3. Initiating a creative collaboration between technical and
domain experts to iteratively refine a conceptual model
that addresses particular domain problems.
http://en.wikipedia.org/wiki/Domain-driven_design
35. DDD and CQRS in My Own Words...
● Domain Driven Design is a philosophy and methodology
in which your domain model should represent the
business problems that your app is actually solving
● Command Query Responsibility Segregation is the
strategy of separating commands from queries, as
opposed to CRUD functionality which is represented in
the same object. CQRS can help you follow the SOLID
principle
36. DDD - Know Your Role!
● Talk to stakeholders and domain
experts
● Strive for a ubiquitous language
● Know the context in which your
API endpoints will be used
● Use this knowledge to develop
your endpoints
37. CRUDY v Commandy
CRUD API Commanding API
Create a Product
Update a Product
Mark Product as Active
Describe a Product
Order a Product
Markdown a Product
Review a products
Mark product as out of stock
39. CQRS and CRUD Can Coexist
PUT or PATCH is just an update command BUT:
● Be very selective with what is allowed to be updated
● It is not always appropriate to expose update
functionality for a particular object or property
● If another command updates a property, updating that
property directly probably shouldn’t be allowed
DELETE is a special use case command too