Why REST is important even for your internal API.

Well, it is actually not REST that is important but to have an consistent, descriptive, discoverable interface, using a common understood definition. REST just happens to be the default one.

Now, most people have realized that it is meaningful to build public API’s using REST, however, when it comes to internal services it is not always the case. ‘REST is overrated’ or ‘It is not that important’ are some of the things I’ve heard people saying when it comes to applying the REST principle to internal services. Some of the (better) arguments are:

  • Only few services, that we have control over, will interact with this API
  • It is easier to communicate the created interface to others within the company
  • We can look at the source code and figure out what we need
  • The API does not operate on resources, it’s just a bunch of functions
  • HTTP response statuses don’t cover the variety of errors within a service

While these points are not completely invalid, they aren’t really enough of a reason not to have RESTful internal APIs.

Only few services, that we have control over, will interact with this API

Having only a few, known services interacting with the API making it seem less important to take a lot of care about the design of the API itself, since it is only necessary make the few services work with it. However, this does not take into account the evolution of the system landscape. The API itself changes, the services evolve and new services may be needed in the future to interact with the API. Thus, it is wrong to just take into account the current situation, but it is necessary to consider the future usage of the API.

It is easier to communicate the created interface to others within the company

For the most part the same argument holds as above. Teams working with the API grow; people leave, people join. Everytime when there is someone new who is supposed to work on a service interacting with the API or with the API itself s/he needs to learn about it. The easier the API is the faster the new person can actively contribute.

We can look at the source code and figure out what we need

Usually every developer who works with the internal API will have access to the source code and thus be able to figure out which actions they need to call and what they will be doing. However, this does not mean that it will be easy to figure out these things. It is not straight forward to navigate big codebases, find the place you are looking for and then understand what it is exactly doing. Often it will take a long time to get what really is going on in the code and this could be, at least partially, avoided if the API is designed in a way that makes it easy to understand and work with.

The API does not operate on resources, it’s just a bunch of functions

This is something that could happen with external facing API’s as well, but especially an internal API sometimes seem like just a set of functions that don’t to operate on resources. For example, there may be an endpoint that causes a DB clean up or an endpoint that just validates input data. So, the bottom line here is that it sometimes is difficult to model the interface correctly based on resources, because there aren’t any obvious resources to work on. However, this does not mean that it is not possible to do that. With a few adjustments of the API and/or creativity it is usually possible to come up with a resource-based design, which will be easier to understand and will be more consistent to the user. Coming back to the examples, the clean up DB task may be an update on the resource ‘DB’ and it may be possibly to move the logic of the validation endpoint to the create endpoint of the resource the validation is for.

HTTP response statuses don’t cover the variety of errors within a service

Within the code of an API there will be a huge range of different possible errors that could happen. The HTTP response statuses only allow for a few rather generic error types, which are way too few to cover all the possible errors. For a public API this is not a problem, since it is not desired to expose the internals of the service to the public. It could help attackers to find security holes. While this argument not holds for internal APIs, it is questionable if the clients that are using the API even need to now the exact error. If there is some exception in the API this will usually result in a 500 response status send back to the client. Now, regardless of the error the client will usually execute the same kind of procedure, because it won’t be able to solve the problem in the API service. For example, it will most likely not make a difference for the client if the error was caused by a bug in the application or because the database is down. In both cases the client can not really change anything about that. I can see, however, a few cases where it might be valuable to have more fine grained error types. If that’s necessary I would still use the response statuses as usual, but enhance them by putting some sub error type into the body, complementing the response status. This way we can still be RESTful and the services, which don’t need the specific sub error types, can ignore them and those who need it can check the body.

Conclusion

The point I am trying to get across here is, that many of the benefits of applying REST to public API’s also apply to internal ones. That does not mean that you always have to go as far as with a public API - It certainly is use case dependent. However, it is very important to carefully think about the design of internal APIs and not just ignore it by using arguments such as the ones given above.