The CRUD Anti-Pattern in REST APIs

Last Update: 24.08.2018. By Jens in Newsletter

Software patterns come and go. As do the anti-patterns. Things you should not do they proved to be bad decisions before. One of the new anti-patterns is the “CRUD Mapping in REST APIs”.
In this pattern, we create an API that represents 1-to-1 our data model and we blindly map our internal data structure to the outside.

For example, if we got a Person entity, which includes an Address entity. in the data model, we also use exactly the same object in the API. Also, the CRUD cycle (create-retrieve-update-delete) are mapped exactly the same to the common HTTP methods used in Rest APIs like:

POST = Create
PUT/PATCH = Update
GET = retrieve
DELETE = delete of model instance

A common way in Rest APIs is to expose each entity as an individual resource and thus having its own endpoint like:

POST /person -> create person in db
PUT /person -> change person, also the person -> address reference
POST /address -> create an address

If we want to change the address of a person now, we would first have to create the new address or update it, depending on how address are stored in the data model, and in another clal we would have to change the address reference on the person entity. Of course, there are some variations to it, but if you, like for example using Spring Data REST, it probably will create such an API (HATEOAS style).

The problem with that is that our API is not driven by a business purpose anymore but rather by the technical data model we use. This can be a new one or existing ones with all their problems. Whatever we do we just expose our data model over a different technology. Instead of SQL or alike, we now offer the CRUD cycle over a Rest styled API. It also comes with a bag of problems.

  1. Every change in the data model will change the API. Change relations in SQL, you have to change the API as well.
  2. The client must make sense of the data again. Instead of working with a business view, it must now understand how the data model is stored and makiing sense out of it. Instead of a business API, we now have just added a new “CRUD over HTTP” layer. However, the API should focus on the business purpose and you want to have that stable as much as you can. Some db storage stuff should not reflect in the API. An API has two goals. Solving a business problem in a way that is good for the client. And second, it should hide the internal stuff. And a bonus is, it is stable over a longer period of time.