REST API? Sure?

October 9, 2026

The problem

A few months ago I took over a micro-service to develop new features. First thing I made was to review the code. Supposedly this micro-service manages and serves a resource named persona through an REST API. And I found that:

/personas/datosPersona, /personas/datosPersonaBasica, /personas/datosCrearPersona, /personas/datosPersonaModificarIdentificaciones, /personas/datosPersonaBuscar

Really? This is supposedly the first version of the REST API. And I found that:

/personas/informarPersona, /personas/informarPersonaBasica, /personas/informarNuevaPersona, /personas/informarBuscaPersona, /personas/informarModificarPersona

These endpoints are the second version of the REST API.

All the endpoints uses the HTTP verb POST.

This is crazy. The resource is persona but the naming of the endpoints seem that there are a lot of resources: datosPersona, datosPersonaBasica, datosCrearPersona, datosPersonaModificarIdentificaciones, datosPersonaBuscar, etc.

These endpoints should be named after the resource they represent:

/persona

Yes, indeed, there is not any standard define by IETF, but a de facto standard exists, and there are some patterns that resolve the different scenarios this microservice should deal with.

The HTTP verb is important

All the endpoints shown above share a common trait, the HTTP verb used is always the same: POST.

This is a mistake, because the HTTP verb that any endpoint uses is bound to some significance:

  • POST for create operations
  • PUT for replace operations
  • PATCH for update operations
  • DELETE for delete operations
  • GET for get and find operations

So, a POST to endpoint /persona means a creation of a persona resource. A GET operation to endpoint /persona means a get or find operation, depends on arguments.

Arguments

There are many ways to indicate parameters to endpoint:

  • path arguments, like /persona/{idPersona}
  • query arguments, like /persona?m=b
  • body arguments, like JSON objects

Each way, combined with the endpoint and the verb implies different actions.

  • path arguments are intended to use for get based on keys like the persona ID.
  • query arguments are intended to use for find operations or filter indications for get operations
  • body arguments are intended to use for create, replace, and update operations

Dynamic models for get or find

Sometimes, specially if the model is heavy, users want to reduce the number of properties obtained.

This can be made with query argument that specify what parts of the model the user want to obtain. The parts of the model are predefined in the same API. In any case, a basic part of the model are ever returned, as the ID, and some other basics properties.

So, in order to reduce the HTTP request length, the query parameter and the arguments should be reduced to minimal expression. I prefer this way and the query parameter I named m, for model.

The values are one character code and are attached to predefined parts of the whole model. These values can be combined, so user can determine what parts of the model want to obtain.

For example, in the case of the resource persona:

  • r Related personas
  • e Economic information
  • c Contact information, like email, phone and postal address
  • g Administration management (for the Spanish word «gestiones»)

So, if user want to get related personas and contact information, the complete call is:

GET /persona/<idPersona>?m=rc

In find cases, user should combine filter query with model query:

GET /persona?f="e=>50"&m=rc&p=1&s=25

That should be interpreted as:

  • f Indicates the filter: age equal or greater than 50
  • m Model is related personas and contact information (basic part is implicit)
  • p First page (Starts at 1)
  • s Size of page is 25

REST API Versioning

This is an essential part for REST API. As the software has version, the REST API that implement should to have version too.

The methods used by people to establish the version are different:

  • path versioning
  • Specific headers versioning
  • Media type versioning
  • Query parameters versioning

Path versioning is made adding a prefix to the path:

/api/v1/persona

Personally I prefer the specific headers method. I use a header named x-api-version.

So in the case I exposed before, the same endpoint is available for both the two versions of REST API.

The endpoints for same operation in the two versions, /personas/datosPersona and /personas/informarPersona will be the same: /persona and the different is only a header.

What kind of version code should be used? There are a general agreement to use a lower letter v and a number, like v1. Also, a number alone is fine. In any case, the number should be the same as the major version of the software that implements it (remember semantic versioning)

Version delivering

How two versions of the same REST API can coexist? Well, depends on the way this is implemented:

  • Two different instances of the same service but different versions (1 and 2)
  • Same instance implements the two versions

The solution depends on the execution environment. If your orchestration system have the tools to run two different instances of the same service, and a filter based on header content is available, then this is the preferred way because the code comes clean. If not, the only one solution is to implement the two versions on the same code, but this method requires an extensive and exquisite code design managing and maintaining.