Spring Auto REST Docs + Spring Data REST? HATEOAS? - spring-data-rest

I really like the idea of using Javadoc comments for auto-generating REST Docs!
Huge parts of our REST API are automatically generated by Spring Data REST (by adding #RepositoryRestResource to Repositories). It would be great if REST Docs could also be generated for these - that would be a very high degree of automatition.
But unfortunately most "auto-"snippets are "empty" (e.g. auto-response-fields.adoc only contains a list of links[]-Attributes). I guess the reason could be that the REST Controllers are probably created dynamically by Spring Data REST. Currently I do not see how to re-use the Javadoc comments for them.
Is there any way to auto-generate REST Docs for such REST APIs that are provided by Spring Data REST?
It would even be helpful to manually tell Spring Auto REST Docs which classes are used in requests and responses instead of letting it discover it statically - is that possible?
And we also add HATEOAS "_links" to most response Resources (by providing ResourceProcessors as Beans). These links contain "title"s which are used by Spring REST Docs - if we list all of them with HypermediaDocumentation.linkWithRel(...). This is a bit redundant, and it would be nice if all the _links with "title"s could be processed automatically. (But this can be done by listing all of them in some extra code, so it is not as bad as with Spring Data REST.)
If necessary, I could also create an example project for what I am talking about.

Answer to the question whether one can manually tell Spring Auto REST Docs which classes to use for the documentation:
Spring Auto REST Docs allows to specify the request and response classes to use for the documentation. This can be done with requestBodyAsType and responseBodyAsType. In a test it looks like this:
.andDo(document("folderName",
requestFields().requestBodyAsType(Command.class),
responseFields().responseBodyAsType(CommandResult.class)));
This is from a test in the example project.

Related

Does HATEOAS contemplate hypermedia in the Error Response?

In a Hypermedia-Driven RESTful solution, should I include relevant HATEOAS links in Error responses?
For instance, let's imagine we have a Microservices architecture.
We have FooSvc and BarSvc, where Bar resources are associated in a 1:1 relation with Foo resources, but managed independently (e.g. we have Projects that we can create just to present them, and then we can decide to Manage a project in our platform).
So, we can try to fetch the Bar resource associated with Foo with id 1 using GET /foo/1/bar (not caring how the request is routed downstream to the BarSvc).
Since there is no such Bar instance created yet, the service will retrieve a 404 response. Should that response include hypermedia links to point out how this can be created (e.g. a HAL _links field with a link to POST /foo/1/bar)?
Definitely, in fact, RFC7807 - 'Problem Details for HTTP APIs' can help with this, and the most popular frameworks should provide support for it (as for example the Spring HATEOAS library here)
Also, there is a proposed vnd.error mime type for this (further explained in this post), but it seems it has been superseded by RFC7807 mentioned above, at least Spring deprecated this in favor of the Problem Details approach (here)

API Versioning in dotnet core

I am working on APIs in dotnet core 2.2 and I'd like to version my API.
I'm looking for some solutions except:
Routing method (api/v1/controller, api/v2/contoller)
Routing method using APIVersioning package, (api/v{version: apiVersion}/contoller})
I want to know if there is any other solutions in which I don't have to change the route attribute? I might be completely wrong but can I use middleware? Like, map delegate to map the the incoming requests (based on v1, v2 it carries) to its right controller?
I'll highly appreciate any feedback and suggestions.
You can use the APIVersioning package and configure it so it selects the version based on the HTTP Header.
services.AddApiVersioning(c =>
{
c.ApiVersionReader = new HeaderApiVersionReader("api-version");
}
And then you can use the [ApiVersion] attribute on your controllers.
Can you use custom middleware - yes; however, be advised that endpoint selection is typically much more involved. The routing system provides extension and customization points, which is exactly what API Versioning does for you. Creating your own versioning solution will be a lot more involved than having to add a route template parameter.
If you're going to version by URL segment, then API Versioning requires that you use the ApiVersionRouteConstraint. The default name is registered as apiVersion, but you can change it via ApiVersioningOptions.RouteConstraintName. The route parameter name itself is user-defined. You can use whatever name you want, but version is common and clear in meaning.
Why is a route constraint required at all? API Versioning needs to resolve an API version from the request, but it has no knowledge or understanding of your route templates. For example, how would ASP.NET know that the route parameter id in values/{id:int} has be an integer without the int constraint? Short answer - it doesn't. The API version works the same way. You can compose the route template however you want and API versioning knows how and where to extract the value using the route constraint. What API versioning absolutely does not do is magic string parsing. This is a very intentional design decision. There is no attempt made by API Versioning to try and auto-magically extract or parse the API version value from the request URL. It's also important to note that the v prefix is very common for URL segment versioning, but it's not part of the API version. The approach of using a route constraint negates the need for API Versioning to worry about a v prefix. You can include it in your route template as a literal, if you want to.
If the issue or concern is having to repeatedly include the API version constraint in your route templates, it really isn't any different than including the api/ prefix in every template (which I presume you are doing). It is fairly easy to remain DRY by using one of the following, which could include the prefix api/v{version:apiVersion} for all API routes:
Extend the RouteAttribute and prepend all templates with the prefix; this is the simplest
Roll your own attribute and implement IRouteTemplateProvider
Ultimately, this requirement is yet another consequence of versioning by URL segment, which is why I don't recommend it. URL segment versioning is the least RESTful of all versioning methods (if you care about that) because it violates the Uniform Interface constraint. All other out-of-the-box supported versioning methods do not have this issue.
For clarity, the out-of-the-box supported methods are:
By query string (default)
By header
By media type (most RESTful)
By URL segment
Composition of n methods (ex: query string + header)
You can also create your own method by implementing the IApiVersionReader.
Attributes are just one way that API versions can be applied. In other words, you don't have to use the [ApiVersion] attribute if you don't want to. You can also use the conventions fluent API or create your own IControllerConvention. The VersionByNamespaceConvention is an example of such a convention that derives the API version from the containing .NET namespace. The methods by which you can create and map your own conventions are nearly limitless.

Changing the JSON format for spring-data-rest

Currently spring-data-rest is returning JSON in HAL format in a spring-boot project of mine. I am using an ember.js frontend and want to use jsonapi (http://jsonapi.org/) specification.
How might I register a new JSON formatting strategy given I will need to write the formatter myself as one does not exists yet?
This is how you can customize the HATEOAS that Spring Data REST produces:
https://docs.spring.io/spring-data/rest/docs/current/reference/html/#customizing-sdr.customizing-json-output
If you need to completely replace the JSON representation with your own, then you can write and register your own org.springframework.core.convert.converter
Or you write your custom REST endpoints in a plain old #RepositoryRestController and implement your own REST endpoints. (<= I suggest try this)

developing your own RESTful API

in developing your own RESTful API. does it necessarilly needed to use the four different http methods? GET POST PUT & DELETE?
i was checking the Twitter REST API and saw that they are just using the common methods (GET & POST)
Short answer: No
Long Answer:
REST is not specific to any one protocol, instead it is a style of programming. This is helpful to keep in mind because a RESTful endpoint should be thought of as having specific goals. Your job is to expose the web service in the most RESTful way possible.
When you're making a RESTful API you are not required to use any specific HTTP methods. Instead, REST can be embodied in this guiding principal: That you must expose individually identifiable resources; these resources must be manipulable in their exposed form. Oh and use self descriptive messages.
I'm sure this is a leaky explanation. Try to see, though, that REST becomes much more clear when you have the key idea in mind. RESTful practices expose resources in a way that allows us work with state in a sane manner. The technical details of how to implement a RESTful API can be learned by reading this:
http://en.wikipedia.org/wiki/Representational_state_transfer
After that, read something specific to your language. Fast track: find some RESTful API written in your language and clone it/play with it.
You should use whatever HTTP methods are appropriate for the operations you expose.
For example, you should accept HTTP DELETE requests only for operations that delete things.
If your API does not allow callers to delete things (eg, a traffic or weather API), you should not accept the DELETE verb.
Only if you are going to support those logical operations:
GET - fetch a resource
PUT - update (or create) a resource
DELETE - delete a resource
POST - several uses: create a new resource in a collection, perform some operation that will alter a resource in some one (as opposed to PUTting an entirely new version of a resource)
Most APIs will want to to provide those operations, and will use all those methods. And don't forget HEAD - fetch information about a resource (but not the resource itself).

Implementing REST hypermedia using WCF

I have a WCF-based REST service and I'm planning to add hypermedia support to it. Currently I'm relying on WCF to build the service response by serializing my data contracts. With hypermedia in the picture now, I need a way to instruct WCF to insert hypermedia links in the XML response that it builds. My question is, how do I do that?
One way could be that I modify my data contracts to include the said links as data members. Then WCF can automatically serialize them. But is that the best practice? Or is it better to intercept WCF's serialization process and add these links at that time? Or is there any other more suitable alternative?
You need to construct the hypermedia yourself. If you choose Atom there are some helpers. Basically you create a SyndicationFeed and add SyndicationItem items to it and use an Atom10FeedFormatter to turn the whole feed into an Atom document.