🇵🇱 Tutaj znajduje się odnośnik do wersji w języku polskim.
In this article, I will explain why I created the API Genie project and how API Genie will improve the process of creating RESTful APIs.
For the past 10 years, I have been working with web APIs. I have worked with GraphQL, RPC, SOAP, etc, but most of them were RESTful.
I will be honest: despite that I like most of the assumptions of the RESTful approach, for several years I have had the conviction that the development of this approach has stopped. Typical problems the developers have while working with RESTful APIs have not changed for a long time, and the answers to most of them are always “here are three alternatives (to versioning), but none of them solves the problem completely” or “I know that this (aggregating different resources in one endpoint) is pragmatic, but it is not consistent with pure REST”. By the way, no one has seen “pure REST” alive!
This is why the idea of creating the API Genie project was born.
In the spirit of API Genie, it should:
In essence, nothing. There are, however, several aspects of this approach that have not been well understood.
First, REST is not a specification, but an architectural approach. In other words, a set of fairly general principles that define how distributed systems should be created. It does not provide any formal specification, nor guidelines, nor software that would support this approach in everyday work.
While these gaps are not a problem for experienced programmers (they can always come up with and adjust the missing pieces to fit the specific situation), they cause a lot of questions from younger colleagues. In addition, everyone can answer the questions a little differently, which leads to misunderstanding (“in the previous project we did it differently”, or “I like this approach more”) and brings discussions on technical issues to an emotional level. And this already weakens the trust in the technology itself.
Second, some of the RESTful API assumptions are irrelevant to most of us. Roy Fielding (the creator of the REST concept) wrote that REST describes a way to create distributed systems that should evolve for decades. To enable the evolution of systems of this scale, they should be isolated (ang. decouple) from their clients. In order to make it possible to evolve systems of this scale, it would be necessary to isolate them from their clients. Since there was no simple way to describe contracts at that time, he postulated that RESTful APIs should be driven by hypermedia. In practice, this means that:
These assumptions are appropriate for some situations, they significantly complicate the creation and use of REST APIs. And most importantly, the vast majority of developers don’t need them!
Instead, developers need other features:
Third, the rigid stance of Roy Fielding, who defended the meaning of the REST abbreviation with zeal. According to him, an API that is not driven by metadata is not RESTful. Such a binary approach led to misunderstanding among developers. What are we actually creating - is it REST or it is not? And if not, what to call it? It lasted until Leonard Richardson proposed the REST maturity model. Since then, using the abbreviation RESTful, we have somehow pretend that it is “almost REST”, but we still don’t create RESTful APIs that would be consistent with the original definition.
The RESTful approach has several very useful ideas:
First, it focuses on resources and their state. A resource is equivalent to an object or entity, that is, something that has a name and makes sense in the context of a particular domain. The resource-based approach is very practical because in any, literally any approach to design, you need to name the “things” you use.
Yes, REST pays much more attention to the state of resources than to operations on them. REST has basically four very generic operations, which are abbreviated as CRUD. Sometimes this generality makes it a bit difficult for designers, especially in approaches like DDD, which focus on operations as much as entities. I will discuss this problem and its solution in future articles.
Second, REST uses existing WWW infrastructure. Ignoring the topic of hypermedia, RESTful API servers are trivial to create in any web framework. This is because REST is based on WWW infrastructure. Using URLs to identify resources - after all, this is the same protocol that we use for websites. Using a uniform interface to represent operations on resources? Here you go, we have HTTP methods and HTTP forms, which successfully use some of these methods. Caching? Monitoring? Here you have ready-made software that does it very efficiently.
API Genie aims to modernize the approach to creating resource-based APIs (of which REST is a variation). The project has three (equally important) goals:
The principles I will follow:
Every question should have one clear answer. In addition to tools, API Genie aims to collect a knowledge base of best practices and typical API examples from different domain.
We are based on the concept of resources. In this respect, we do not
differ from REST. A resource (Eng. - resource) is something that has a name
and identity. Employee
, Credit
or Onboarding
can be a resource.
We use URLs to identify resources. Like above, the vast majority of resources are identified by URLs. If a resource only exists as a component of other resources, it may not have a dedicated URL.
We use HTTP methods to represent operations on resources. This is the last principle borrowed from REST. Using standard HTTP methods allows for full use of the semantics and infrastructure of WWW and frameworks.
The schema is the source of truth for the API. A schema is a formal description of an API that allows for the separation of the contract from the implementation. Having a formal schema has many advantages, including:
Code is a derivative of the schema, and in most cases should be generated. In other words, if code can be generated based on the schema, it should be generated.
Generating code has many advantages, including:
Of course, creating generators is a more complex task than writing a REST controller. Fortunately, this field has been well-developed, and the way to generate code is similar for most technologies.
The approach to API development should be pragmatic, not pedantic. API Genie is supposed to solve real problems for developers. While sticking to the rules is generally good, sometimes it is necessary to make exceptions. Of course, they should be made consciously, with an understanding of the impact on the desired API features, such as ease of usage or performance. And it should be remembered that exceptions should be relatively rare (say, 2% of cases), in order to remain exceptions.
Compatibility with existing technologies must be maintained. I believe that we should use the experience of our predecessors and apply our effort to what has already been done. In this way, we will avoid reinventing the wheel and generally accelerate progress.
API Genie tools will be compatible with the OpenAPI 3.x standard and newer. This will remain the case. However, I do not exclude the possibility of adding support for other description standards.
Tools should support developers in every task. In practice, this means that tools will be integrated with editors, IDEs, and browsers (as the most commonly used API clients). They should be as accessible as a toothbrush.
The adoption of the schema-first approach should be gradual. Migration from the schema-less approach (as the most commonly used currently) to the schema-driven approach can take a lot of time. Therefore, API Genie tools will enable gradual migration, so that the implementation is more pleasant.
Now let’s get to work.