<aside>
📝 The contents of this page are super abstract, but we thought it worthwhile to go ahead and publish these thoughts anyways.
The longer I’ve been developing APIs the more convinced of these principles I become.
More concrete examples and case studies are coming soon.
</aside>
We have a broad stance we refer to as “URI is King”, which consists of the below principles. These aren’t our ideas; they come from the early days of HTTP, but we embrace them wholeheartedly even where others may not.
Idiomatic HTTP: An API is an abstraction layer, in which the client requests resources, by their Uniform Resource Identifier (URI), and the server sends its representation of them. Resources and representations are completely independent of how that data is actually stored on the server.
Again, this is just a core principle of HTTP, applied in the context of APIs.
Hypermedia: Clients should be completely decoupled from the server’s URI scheme. Aside from entry points with a known URI, servers should send hypermedia representations of their resources, which contain fully-rendered links to other resources. A client should never have to construct a URI from a template.
Hypermedia is a decades-old concept. HTTP is the hypertext transfer protocol, and this is most relevant in the context of HTML pages that contain links to other pages, which together form the world wide web, as envisioned by Tim Berners-Lee. Roy Fielding notably emphasized this concept as it relates to APIs when he proposed REST; it’s incorporated in a REST constraint called Hypermedia As The Engine Of Application State (HATEOAS). Veneto is not REST, but we embrace the importance of hypermedia separately.
Let’s discuss each of these principles separately:
Veneto emphasizes resources as a unit; the resource is the most granular element of an API, and HTTP methods are simply a “part” of the resource. This comes in contrast to some tools which treat different methods on the same URI as entirely separate endpoints.
The main culprits we’re referring to are other test clients and popular server-side HTTP routers. Test clients like Postman have to represent different methods on the same URI separately in order to supply them with different response bodies, test conditions, and documentation; this makes it cumbersome and inefficient to use or understand the API through the client. Many server-side HTTP routers do the same - endpoints are declared as a combination of a method and a URI template - which leads to repetitive logic.
On the client side, Veneto will address the issue in two ways: first, the API is defined in the domain model, which concisely represents resources as a Resource Class, providing documentation and defining inputs and outputs. The test client uses these definitions to inform the presentation of the API within its user interface.
On the server side, the Veneto toolkit will provide a Standard bidirectional URI mapping. This does two things. Firstly, in lieu of an HTTP router, it will parse URI information and extract the relevant information for the programmer, so that they may perform any relevant data fetching in one place. Secondly, it can do that in reverse, which is useful for working with Hypermedia in practice.
Veneto strongly emphasizes the usage of hypermedia. As we mentioned in the Manifesto, this is a rather unpopular stance among most API developers, so we want to provide rationale for it and outline the benefits it unlocks.
These are the issues we mentioned earlier:
If the server ever needs to change its URI scheme (which happens more often than you might think for products in development), URI templating breaks. With hypermedia, the server always gets to decide what the URI means, and there is almost always a way out of breaking changes to the data model.
Moreover, the API is free to create separate classes of resources that relate to the same data under the hood; this gives rise to a sort of polymorphism that’s opaque to the client and therefore resilient and robust over the long term.
URI templating is messy and cumbersome. To evaluate a URI template, the client must have all of the relevant parameters at the call site, which introduces unnecessary data handling requirements.