We call discoverability to the ability of an API to expose its interface and types.
In a truly RESTful Web Service, where the hypertext acts as the engine of the application state, when a resource its returned it is also revealing every available transition in it. This means there is no need to exchange complex documents describing the operations in the API. The degree of information of the transitions will depend on the specification used to describe links. Some allow to specify the schema of the input fields of an operation. Clients can make use of Content Negotiation to try to select which Media Type they want the resource of a link to be represented.
The OPTIONS
method might be used as well to gather information about who to interact with a service; it will return the available HTTP methods to a certain resource.
REST-Like Web Service, in contrast, are driven by RPC-Like calls made from the client. The specification of how these RPC-Like calls are built is usually provided in a human-readable documentation. Solutions like OpenAPI promote the creation of an ecosystem to improve the development experience:
- Swagger UI renders an in-browser interactive documentation for an OpenAPI schema.
- Swagger Codegen can generate a client library in over 40 programming languages.
GraphQL natively supports introspection, a feature that let client applications ask a server about the operations and types it supports. This is done running a querying the __schema
field:
{
__schema {
types {
name
}
}
}
This will return the name of every type in a GraphQL server.
gRPC, similarly to what OpenAPI with Swagger Codegen does, let API designers define a schema in a certain IDL, and then a language-specific library can be autogenerated out of it using protoc
.
In addition, there are initiatives to provide service introspection using the gRPC Server Reflection Protocol. Similar to GraphQL introspection, it provides info about the exported operations as well as their type (unary or stream), their arguments and return types. This protocol is defined using .proto
definition, grpc.reflection.v1alpha
.
We can easily discover the available HTTP methods in our /distances
REST resource running:
curl -X OPTIONS -v http://localhost:4000/distances
Which will specify that only GET
is allowed:
Access-Control-Allow-Methods: GET
In the example above we saw how to fetch every type defined in a GraphQL server. Now, let's run this query to fetch details about our Article
object:
{
__type(name: "Article") {
name
fields {
name
type {
name
kind
ofType {
name
kind
}
}
}
}
}