What is your favourite standard?

Did you know there is a place on LinkedIn where professionals work together to give advice to other professionals? I contributed to the collaborative article "How to choose between API-first and code-first approaches" Feel free to check what I and many others have written on the topic.

My text will also be part of the book "Mastering RESTful web services with Java" I and a few co-authors are writing.

But even before discussing if specifications should come first or only after code has been written, we should know why we actually need the specifications.

Here is the section from the book that explains it using the analogy with Java encapsulation:

From Java we know the principles of object-oriented programming. One of those principles is encapsulation. We should try to make as many as possible of the members of a class private. We only make those members (usually methods) public that we intentionally design to be accessed from outside the class. The public members combined make the API of the class. It is a good practice to accompany the public members by Javadoc, so that their usage is clear without seeing the code implementing the class. By limiting the size of the public API, we keep the liberty to change or remove the internal (private) members without breaking the code outside the class.

We should also be cautious when defining the signatures of the public methods. Passing unnecessary data via arguments or return values can cause unnecessary coupling, increase complexity of the code processing the data (e.g. validations or ensuring immutability) and limit the possibilities of performance optimization.

A poorly designed API, whose structure is driven more by ease of technical implementation than business requirements, exposing things that should have been hidden, once in use, is hard to change because there may be clients out of our control who depend on it.

If the above is true for APIs connecting parts of a single Java program, designing interfaces that are clearly separated from the implementation and well-documented is much more important for REST APIs crossing the boundaries of individual programs.

Although it may be necessary to provide API users with some additional information using prose, we can greatly benefit from describing as much as possible of our API using a formal and machine-readable specification language. For REST APIs the most widely used and advanced standard is OpenAPI.


Update: I received an interesting reaction that made me realise that the word "when" may not be enough for distinguishing between "specification-first" and "code-first".

Let me quote the reaction: "I am curious if you consider creating Java controllers and request/response objects with springdoc annotations code first or spec first?" Its author also wrote: "I think code first is misleading. It could be implementation first. Just because I don't use common spec doesn't mean I don't do spec first. Which of the pros of spec first can't be applied to this, except it is common spec."

I think the idea is that you can do specification-first (i.e. create an API specification before implementing the service the API exposes) without writing an OpenAPI document manually. Instead, you can use Java with SpringDoc (Swagger) as your specification language. Then you can generate OpenAPI for use by anyone interested.

To me, it is like when you use Hibernate (the Object-Relational Mapping framework), you can let it generate all the SQL to create the database tables for you from your Java code. Is it a good idea? Maybe it is, for a prototype. For production, I would not recommend it.

In a production system the database schemas tend to be more stable and harder to change than the code accessing the data. With microservices architectures when the database schema is accessed by just one service developed by just one team, changing the database schema may be easier. The most stable part usually moves to the service APIs that the many services have to use to talk to each other.

Therefore, I am reluctant to call the "Java controllers, DTOs and annotations-first" approach "specification-first". The main reason is that there is no separate and cohesive specification document and that decreases the value of the specification. The specification code is scattered across multiple classes and once you start with the implementation, the specification code becomes tightly coupled with the implementation code.

When you need to change the API specification, you have to think about what parts of the code need to be changed and how so that the change is clear to the API consumers. You usually want to generate the OpenAPI specification from the code, so you often end up thinking in terms of OpenAPI structure, but having to translate it back to the Java code it is generated from.

You usually need to combine your scattered annotations with a Spring bean configuration that actually copies the structure of the OpenAPI specification:

So it is not only important "when" you do the specification, but also if the resulting specification is "strong enough" to sustain various possible (future) use cases, including

This is why I think using widely accepted open standards like OpenAPI brings benefits that may not be obvious from the beginning.

I mentioned switching Java frameworks above. The vast majority of our book uses SpringBoot to demonstrate the API implementations because it is the most popular framework currently. However, one chapter that I will be responsible for, shows that the same API design principles can be used with other frameworks.

New Java frameworks can bring interesting business benefits, for example Quarkus

Another good news is that there is the MicroProfile standard that the new frameworks including Quarkus implement. If an application deliberately uses the API standardised by MicroProfile, it retains the possibility to switch the frameworks. So even with Quarkus it is a good idea to try to do without extensions that are not (yet) part of the MicroProfile specification.

Our "Mastering RESTful web services with Java" book is a collaboration of five authors. It is great because despite the busy schedule of each one of us, together we will be able to write the book in a reasonable time. Even so, it is quite a lot of work and I want to avoid the situation that the book starts becoming obsolete very quickly after its release date.

This is why I pay special attention to the parts of the book that are the most likely to last longer. And those are exactly the parts connected with the abstract, vendor-independent standards: REST, OpenAPI and MicroProfile.

And what are your "favourite" standards?

Back to all blog posts