Does Swagger 2.0 enable impure REST API design? - api

The current Swagger spec claims that Swagger is used to describe and document RESTful APIs. I think this is not the case rather I think Swagger is useful for simply describing a HTTP API for a few reasons:
The Swagger spec has elements like Path and Definition but they don't clearly map to the REST data elements like resource, representation, and media types. My thought is that to effectively describe a REST API, you should be required to define the explicit REST data elements in the context of your API.
Hyperlinks are not first class objects in the Swagger spec and thus hyperlinks and their critical descriptive attribute, link relation, can easily be left out. In fact, hyperlinks are not mentioned at all.
HTTP paths are at the front-and-center which seems to be a clear violation of a point Fielding made in his famous blog post:
A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server)
Essentially, I think APIs defined using the Swagger 2.0 spec leads you to design an API that isn't constrained by HATEOAS which would violate REST.
Is this correct or am I missing something?

I absolutely agree. Swagger is not well suited for defining truly REST compliant APIs. The problem is that people define REST in a lot of different ways. The Richardson Maturity Model helps describe these different definitions.
Level 0 REST APIs pipe all requests through one URI and one HTTP method. This level includes any API that uses HTTP no matter how limited. In practice, people rarely call this REST anymore, but it does happen (probably for marketing reasons).
Level 1 REST APIs employ many URIs, but still only use one HTTP method (usually POST). Again, in practice, this rarely called REST anymore, but there was a time when it was common.
Level 2 REST APIs are where the concepts of resources and uniform interface are introduced. These APIs have URIs that represent resources and use the HTTP methods to perform CRUD operations on those resources. In practice, people started referring to this as RESTful to distinguish it from Level 1. I credit Ruby on Rails for popularizing this interpretation of REST, but I can't back that up. In any case, when Swagger claims to be for describing RESTful APIs, Level 2 is the definition they are referring to.
Level 3 REST APIs are fully compliant with the REST architectural style. In particular, they are characterized by using HATEOAS. All of the concerns you laid out in your question aren't taken into account until this level. In practice, some people have started calling these Hypermedia APIs to distinguish them from the now entrenched definition of RESTful as referring to the Level 2 definition.
I would say that your understanding of REST is more "mature" than that used by Swagger and therefore, you will only be frustrated trying to use it (I speak from experience). My personal choice for defining Hypermedia APIs is JSON Hyper-Schema. It can't match all the great tools Swagger has, but it allows me to write APIs at Level 3. That's more than I can say for any of the popular API definition languages out there.

Related

Impenetrable confusing definition of API

So I was going through the Wikipedia page on API, in the first paragraph it is stated that
A document or standard that describes how to build or use such a connection or interface is called an API specification. A computer system that meets this standard is said to implement or expose an API. The term API may refer either to the specification or to the implementation.
While I understand the 'specification' part of the definition, I didn't get what 'implementation' here means.
Taking Python as an example, whenever I'm writing a program in it I understand that I'm using it's API specification (or API), but what does 'implementation' mean here? Is it the source code of the Python that was used to build this API or object code or something else. And if it really is source code or object code, then it feels counter-intuitive to call them as API to me — so far in my experience I used to see only specification as API. So, if you could kindly help me to resolve this long lasting query, I'll be highly grateful. Thanks.
Sometimes, people use the term 'API' to refer to a library that implements a particular API. This strikes me as a mis-use of the term, but it might be what motivated the Wikipedia article to say "The term API may refer ... to the implementation". There's some discussion of that on the article's 'Talk' page.
"The term API may refer ... to the implementation" is just a suboptimal wording.
Just take the later in that wikipedia article "The calls that make up the API are also known as subroutines, methods, requests, or endpoints. An API specification defines these calls, meaning that it explains how to use or implement them." which points to what I would phrase "the way you call functions, methods, etc. in a programming language are part of the 'API' of that programming language".
The thing that I stipulate the author of "... to the implementation" meant. You could contact him/her directly to clarify that.
It is complicated because API, protocol, ABI have quite some overlap. "API" is in practice the catch-all for saying "something interacts in a controlled way with a system. May it be an Interpreter, an HTTP-service, a dynamic library (because it is ... "an interface (of some kind) to a system" (of some kind).
That said: "implementation" is IMHO a misleading wording. The API is the interface.
If I do a GET request to nginx or apache ... the "API" would be HTTP and the implementation however nginx and apache do to reply to the HTTP request.
If I do a function call to a Python function the API is the function signature; if the backend (what I would call the "implementation" is CPython or PyPy is not the API but the implementation.
The pointers to the talk page for that wikipedia article are worth a lot!
API and implementations with analogy
I like to think of APIs and implementations with a help of an analogy with some real-world devices, like a car for example. Each car has a steering system, which helps you steer the car (obviously). But in order to use this system, you don't have to know how it works and how it's implemented, so you interface with it via a steering wheel. This also has the benefit of each car manufacturing company having a relative freedom of how they can implement the steering system (because at the end of the day all the driver is worried about is the steering wheel). So in this example the steering wheel would be your API/interface, the steering system is the implementation and the driver is some client application.
APIs and implementations in code
This works similarly in code. When developing a software system or a library, you always choose which components (classes/methods/variables) are exposed to the client applications (the ones which use your system/library), and which ones stay hidden from them and become an implementation detail. The first is the API while the latter is the implementation. Imagine you develop a library of collection classes and utilities, and as part of your API you expose a sort(collection) function, which, as the name states, sorts a collection. Client applications will call this API without caring how it's implemented, so later you can change the underlying sorting algorithm without breaking any clients (they probably won't even know something changed, they are just calling the function same as before). In other words, your implementation can change without any changes to the API.
API specifications
Now, where the wording can get confusing is when we add API specifications into the mix. API specifications are often human-readable documents which describe said API (what classes/methods should be there and how they should behave). Such specifications are not code, they are just text-based documents aimed to guide developers to provide an implementation for this API. When a library implements such API specification, it will contain the actual API (code components which correspond to the specification and are exposed to the clients) and implementation (code components hidden from clients which do the actual work and are called by the API). Now, where confusion lies is that the whole library (including both API and implementation) can be called an implementation of the API specification (because this is actual code implementing what is written in a text document, even though this code contains both API and implementation). I think this is what is meant in the Wiki:
The term API may refer either to the specification or to the implementation.
meaning that when you hear the term API it can refer to either a formal text-based document describing said API or to the actual code components which form the API of some software implementation.
Word on Java interfaces: Java interfaces are basically code components which only have an API, meaning they have no implementation and are meant to be implemented by other classes. This allows developers to have API specifications in code so to speak, where they provide a package which contains only interfaces, and other vendors can use those when developing their implementations. This lets you enforce the specification more reliably, because now instead of simply relying on a document, implementation developers will add those interfaces as code dependencies and rely on the compiler to check whether they implemented every method correctly (of course they still need to worry about the intended behaviour themselves). That said, this only adds to the confusion, because now actual code can also be called an API specification.

Are nested resources RESTful?

How architecturally sound and up to industry standards nesting resource representations in REST APIs is, especially when it comes to nested lists of resources (like books of an author)?
I'm interested in finding links to authoritative sources that answer to this question.
The authoritative source for REST is the dissertation of Roy Fielding, based on work he did during the standardization of HTTP/1.1 (RFC 2068, RFC 2616, etc) in the 1990s.
REST defines resource ("Any information that can be named can be a resource..."), and requires that all resources understand messages the same way (uniform interface) but does not actually constrain your resource model.
"RESTful", historically, is context sensitive; in practice it means something like "more like REST than our current designs". In the web services community, it meant "more like REST than WS-* and SOAP". In Rails, it meant more like REST than the resource models that were recommended prior to Rails 1.2. And so on.
If what you are interested in is describing the relationship between a resource that is a collection and a resource that is an item in that collection, then the standard you want is RFC 6573.
But again, it doesn't tell you how to design the resources, or how to design the identifiers for those resources -- it just tells you how to indicate a relationship between them.
As far as I understand the web resource is something abstract identified by the IRIs and accessible through the web. What dereferencing the IRI gives back is the representation of the actual state of the identified resource, this is why it is called representational state transfer. I don't remember any standard that discusses nested resources. Maybe RDF is the closest what you are looking for. In practice if we follow RDF concepts, then to answer a GET request the REST API responds with a representation of an RDF subgraph starting with the resource indentified by the giving IRI and it can be any level deep. Nestedness is not something I would consider here, because it is a graph, not a hierarchy, it is sort of expanding relationships between resources or returning hyperlinks the API consumers can follow to do the exact same thing.
Not sure if this helps. I did not find any RFC beyond what VoiceOfUnreason's answer contains, I remember to read explicitly about web resources and identifying real things with hashtags or non-dereferenceable IRIs in an RFC 5+ years ago, but I have no idea which one it was. Maybe it was the Lanthaler dissertation or the SemWeb document VoiceOfUnreason suggested. What is certain it was somehow connected to the semantic web and RDF.
REST’s identification of resources constraint requires that resources
are identifiable so that they can be accessed and manipulated via
generic interfaces. On the Web, resources are identified by IRIs [44].
Since a resource may represent con- cepts which cannot be serialized
into a byte stream (e.g., persons or a feeling), resources are not
manipulated directly. Instead, REST is built on the concept of
manipulation of resources through representations; i.e., an additional
layer of indirection in the form of resource representations is
introduced.
https://www.markus-lanthaler.com/research/third-generation-web-apis-bridging-the-gap-between-rest-and-linked-data.pdf
On the Semantic Web, all information has to be expressed as statements
about resources, like the members of the company Example.com are Alice
and Bob or Bob's telephone number is "+1 555 262" or this Web page was
created by Alice. Resources are identified by Uniform Resource
Identifiers (URIs) [RFC3986]. This modelling approach is at the heart
of Resource Description Framework (RDF) [RDFPrimer]. A nice
introduction is given in the N3 primer [N3Primer].
Using RDF, the statements can be published on the Web site of the
company. Others can read the data and publish their own information,
linking to existing resources. This forms a distributed model of the
world. It allows the user to pick any application to view and work
with the same data, for example to see Alice's published address in
your address book.
https://www.w3.org/TR/cooluris/#semweb
So what I want to say that what you see in the HTTP response is not the resource itself, just a representation of it and its relationship to other resources.
REST does not have a constraint which tells you how verbose that response must be. It just tells you that you must use hyperlinks to connect resources and that you must use standard MIME types and document your API. At least this is how I interpret the uniform interface constraint.
I think the question is very good, because this part of the architecture is open and there were many questions in the past years which ask how to use the URIs for querying nested resources. The answer is always that REST does not cover it, the URI and URI template standards don't cover it either. There are standards like OData and Hydra, which have suggestions, but it is just up to you. Your problem is connected to it, because it asks how verbose a response to such a query can be. It is not covered as well as far as I can tell, but what is certain that it can and must contain at least hyperlinks to other resources. RDF allows describing several resources in a single document, so if we extend the RDF approach to REST, which does not say this is forbidden, then I guess we can do it.
From practical perspective for example a collection is a sort of nested resource too and if the API consumer would send a dedicated request for every collection item just to know basic things like product names, then it would be wasting resources. Normally we respond this kind of requests with a single HTTP response or multiple ones with 25-50-100 items on a page. It does not make much sense from usability and scalability perspective to give hyperlinks to the consumer for each item and force them to follow those links one by one. In fact we like to respond with the exact view model the consumer needs and design APIs this way. I think the same is true for nested properties as well. From RDF perspective these responses represent a subgraph of a massive resource graph, which are managed by the REST service and by for example RDF vocabulary maintainers like OWL, Schema.org, etc.
So to have a one sentence answer: the representation of "nested resources" is not covered by REST and as far as I know not covered by standards like HTTP and URI either, but currently it is the best practice to use them and MIME types we frequently use for REST e.g. HAL+JSON or RDF/JSON-LD support nested representations too, so I would say yes.

Why does HATEOAS not specify a schema for the request body

A question for this already exists, but is more tech focused and doesnt have answers: Representing a request body on HATEOAS link
I like HATEOAS. I love using it in my frontend to check if I can perform some actions by checking if a link exists instead of having business logic.
But what I do not understand is how HATEOAS can truly be useful in other scenario's. What if you have an "AddItemToBasket" link which would need a request body with some properties in it. The frontend would still need to know what this request body looks like. But HATEOAS doesn't tell you this.
This means you still have a dependency on API knowledge. I think lots of applications solve this problem with generated API clients/graphql, but that makes HATEOAS a hard sell.
Why use HATEOAS if we can't use the URL and http method, because it doesn't offer the full picture.
REST builds on standards (uniform interface constraint) and currently there is no standard way to do this. There is a Hydra W3C WorkGroup writing a standard about how to describe Hypermedia APIs. They use RDF, standard vocabs like schema.org and you can write your API specific vocab they call documentation. As far as I understand their model you can give parameters in the documentation for operations represented by hyperlinks. You can use for example XSD to add constraints like numbers, etc. to the parameters. It takes a lot more effort than normally to write this kind of formal documentation and as far as I understand there are currently no general REST clients which could profit from these, so it does not make much sense currently to write such an API, but it is possible if you want to.
As of why to use HATEOAS, it makes your API flexible and backward compatible. For example if somebody does not have permission for an operation, you simply don't send a hyperlink for it in the response. You can always add new operations and the existing clients don't have to support them, they can just focus on what they already know and they won't break because something extra is added. They don't have to know about the URI structures and the methods, which can freely change if the only thing they depend on is the operation type and the parameters.

A few questions about RESTful APIs and why some of the best-practices are rarely implemented

In most tutorials, documentation, articles etc. about RESTful I come across a few of the same points, but yet I rarely ever see these 'What makes it RESTful' points implemented.
For example, I've read this many times:
Content type
Using HTTP headers
Accept: application/json, text/plain
Extension in the URL
Not RESTful, URLs are not the place for Content-Type
I have never come across an API where I have seen this implemented. Every API I have ever used has always required me to append XML or JSON to the end of the URL. Are they doing it wrong?
Versioning
Version media types
application/vnd.something.v1+json
Custom header
X-API-Version: 1
Version in URL
/v1/resouce
Not RESTful, by putting the version in the URL you create separate resources
If you need to introduce non-backwards-compatible functionality surely creating a seperate resource is the correct thing to do?
Once again, in all versions of APIs I've used, they use v1, v2 in the URL (such as google, imgur etc.)
By not implementing these points, would my API not be considered RESTful?
To clarify these points would be much appreciated.
1) Using accept header or using format specific URLs are both valid in a RESTful system. The article you are citing is wrong.
2) Saying v1/resource is not RESTful is also incorrect. You cannot look at a URI and make a conclusion about its RESTfulness. Adding a v1 at the root of your URL is probably not a great thing to do if you are trying to incremental evolve your system. In effect it declares a whole new URL space and obsoletes the old one. That's pretty drastic. RESTFul systems try and enable incremental and evolutionary change to a system. So doing /resource/v2 is actually much more compatible with that goal.
The unfortunate phenomena at work here is that many developers who are learning about REST discover that the vast majority of systems out there that claim to be doing REST are not actually conforming to the constraints of REST. So they quickly develop a zeal for telling everyone what is and is not RESTful. Many of these people have not yet fully understood the constraints and end up making up new ones that don't exist. The "RESTFul URL" fallacy is a classic. "POST must create a resource" is another common one.
My guidance to anyone learning REST is, if someone tells you that something is not RESTful, you ask them what constraint it is violating and what is the practical impact of ignoring that constraint. If they can't answer that, then politely ignore them.
The true definition of REST is obviously in the doctoral dissertation written by Roy Fielding in 2002. Do all of the API's out there that call themselves RESTful follow the guidelines specified by Fielding? The answer is no. The definition of REST has been watered down by some to just mean anything that does not use SOAP. I would worry less about what is RESTful and more about what is good practices. It is a good practice to specify the content type in the header of the request. It is also a good practice to version your API's. A good resource for information on API best practices is from the guys at Apigee as they have a lot of experience in this area. Check out their webinar on RESTful API Design where they ask if you are a pragmatist or a RESTafarian.

REST type API for non web based applications, Is It a good idea?

We are developing a middleware SDK, both in C++ and Java to be used as a library/DLL by, for example, game developers, animation software developers, Avatar developers to enhance their products.
Having created a typical API using specific calls for specific functions I am considering simplifying the API by using a REST type API (GET, PUT, POST, DELETE) or CRUD type (CREATE, READ, UPDATE, DELETE) interface.
This would work in a similar way to a client-server type REST API where there are only 4 possible API calls but these can take flexible parameters.
This seems to have the benefit of making the API stable in that new calls are not being added and old calls are not being removed. So a consumer of this API need not worry about having to recompile and change their code to suit any updates to our middleware.
The overhead is that there is an extra layer of redirection in the middleware controller to route API calls and the developer needs to know what parameters are available for each REST call (supplied of course).
I have not so far seen this system used outside of web type client server applications so my question is this: Is this a feasible idea?
I am thinking in terms of its efficiency as well as if for example a game developer would find it easy to use.
Yes, this is a feasible idea. But I'm not sure the benefits would justify the costs. REST is best applied to a networked application scenario, oriented around requests and responses. While there are definite learning curve advantages to a uniform interface, those advantages can be present in almost any well-designed API which provides reasonably abstract procedures.
You also expressed concern for whether a game developer would find a RESTful API easy to use. I'd be dubious. I've implemented many RESTful web services, and helped many developers get up to speed both building them and using them, and the conceptual leap required to grasp REST can be substantial for someone who has been steeped in procedural APIs for years. I'd think that game developers in particular would be very strongly connected to procedural APIs, to the point that attempting to adopt a different paradigm, whatever its benefits, might prove extremely difficult.
Remember that REST is not specific to HTTP, and does not rely on just the 4 HTTP verbs. The verbs you have and can use depend on what protocol you're using.