ScaCap / spring-auto-restdocs

Spring Auto REST Docs is an extension to Spring REST Docs
https://scacap.github.io/spring-auto-restdocs/
Apache License 2.0
311 stars 86 forks source link

Contents objects not shown in HTML -- possible generics problem. #186

Closed wolverine2710 closed 6 years ago

wolverine2710 commented 6 years ago

In response to jmisur for issue #183. I've created a sanitized version of my test code. It should be complete and being able to help you pinpoint where it goes wrong.

Original post: "We handle our JSON responses in a generic we and use a RESTResponse object for it. Code: return RestResponse.create(, HttpStatus.CREATED); RestResponse generates two JSON objects, meta{} and data{}. Meta contains the RestMetadata object. Its has a fixed number of fields AND SARD shows info for those field. The data object however changes all the time depending on what object we create and hence the fields in it. The only output we get from SARD is data (Path) Var (Type) false (optional) and a generic description. It is somehow possible to show the fields of . Thats essential for us."

We've done some more digging. Wrt to file RestResponse. It looks as if Spring Auto Rest Docs doesn't like generics or doesn't go/dig deep enough. private T m_data; holds the data (using generics). Replacing this by Object and still using generics doesn't solve the problem. If however we create a RestResponse class for a specific domain or JsonObject it of course works. For example see the file RestResponseGoodFaultExample.txt

We use 'spring-auto-restdocs-core', version: '1.0.10' and Spring 4.3.7.RELEASE'

If you need more info please feel free to ask.

RestDocumentsExample.zip

jmisur commented 6 years ago

Hi. It took me some time to make your example work. Anyway I realized what are you trying to do.

Basically the result is: you cannot use generic response parameter with SARD. That's for one trivial precondition - all endpoints must return static predefined structure in order to be documented. If your endpoint returns class1 in one case and class2 in another case, how do we determine which response fields to use? How do we know which classes are actually possible to return from the endpoint? You need 2 tests to return 2 different classes anyway, and in that case 2 different documentations will be provided.

We are not inspecting classes which are returned from an example call. This is for very simple reason, that example response can be very limited in amount of fields you can produce at the same time (some might be mutually exclusive; or some might be missed if you use JsonSubtype annotation). That's why all resolution is static and very predictable.

Possible options for you:

  1. use classic SRD
  2. create class hierarchy using JsonSubTypes (see ItemResponse.Metadata example)
  3. create custom response object just for documentation which will contain all fields from all possible response classes. See ItemResourceTest#processAllItems
wolverine2710 commented 6 years ago

Thanks for the reply, unfortunately I´m on holdiday this week and return to work after X-mas. I will try to interpret/digest what you wrote and gonna look if I can work around it.

Wrt solution (1). I guess then I can´t use SARD at all OR can SRD and SARD somehow be mixed?

fbenz commented 6 years ago

You can even combine SARD and SRD in the same test. In an usual SARD setup, you can use MockMvcRestDocumentation.document with the usual SRD constructs like PayloadDocumentation.responseFields. For manually documented response fields the result ends up in request-fields.adoc and not in auto-request-fields.adoc and is thus not included in the section snippet's auto-section.adoc. But of course the snippets can be manually included in the documentation - just like it is done in a pure Spring REST Docs setup.

I created a small demo in the example project: https://github.com/ScaCap/spring-auto-restdocs/pull/199

ghost commented 6 years ago

We had a dev meeting, discussed the POC and the decision was made to switch from SRD to SARD. SARD is still relative young but the progress made in the last year and the PR's submitted give us a good feeling. Undoubtly we will experience some 'challenges' .....

Thanks for the example of combining SRD and SARD, very much appreciated.

Gonna have a look at bullet point (2) and the other points. Have some serious reading to do it seems. I'm not fluent in SRD and certainly not SARD (yet).

Atm we are contemplating/implementing the following. AbstractAutoRestResponse class which contains only the meta data. For every existing and new REST controller we create a class which extends from AbstractAutoRestResponse (so we have the meta data) and specfy in the data. Hence for StudentRestController we create a StudentRestResponse class and so on. Is this a valid way or not...