spring-projects / spring-data-rest

Simplifies building hypermedia-driven REST web services on top of Spring Data repositories
https://spring.io/projects/spring-data-rest
Apache License 2.0
924 stars 562 forks source link

Wrong property type in JSON Schema for lists with a @DBRef annotation [DATAREST-1096] #1461

Open spring-projects-issues opened 7 years ago

spring-projects-issues commented 7 years ago

Marc Mannig opened DATAREST-1096 and commented

We found a confusing problem with the returned JSON Schema in combination with the mongoDB @DBRef annotation and lists. List of objects which are embedded in the document are correctly described by the JSON Schema i get from /profile/theresource. But if i want to store the objects in a different mongoDB collection and simply add @DBRef to my list in the root object, the JSON Schema returns "string" instead "array" as type for the list property.

You can find a simple example with unittests which describes the problem under: https://bitbucket.org/martinschueller/data-mongo-rest-test (No DB needed)

The last test "shouldAlsoRetrieveTypeArrayWithDefinition" failed, because of the wrong type.

The problem occurred with all springboot versions


Affects: 3.0 M4 (Kay)

Reference URL: https://bitbucket.org/martinschueller/data-mongo-rest-test

2 votes, 5 watchers

spring-projects-issues commented 7 years ago

Greg Turnquist commented

If you apply a @DBRef annotation to the field of a domain object, Spring Data REST's PersistentEntityToJsonSchemaConverter will flag that attribute as a Reference. Instead of looking up the characteristics of the field (List<Email> in this case), it will instead presume that it's a URI reference to another resource, in which a URI is, in fact, a string

spring-projects-issues commented 6 years ago

Martin Schüller commented

@gturnquist exactly. That is what we assumed. However, this is the only occasion where there's no way to find out the proper type of the corresponding object. For typed languages to create models on the fly by fetching the JSON Schema it always works, almost. Arrays in DBRef are the only exception.

By combining the information of

curl -X GET http://enroot.herokuapp.com/profile/clients -H 'Accept: application/json' 

and

curl -X GET http://enroot.herokuapp.com/profile/clients -H 'Accept: application/schema+json'

We can build typed classes from it. The only restrictions is DBRef arrays. Since we also know all methods etc. we can build forms, visual representation and everything from it. What would be a workaround?

we know we are misusing ALPS and schema+json by doing this, but it's very powerful when combined ...

spring-projects-issues commented 6 years ago

Christoph Huber commented

I provided a pull request for this some time ago (https://github.com/spring-projects/spring-data-rest/pull/285). In my oppinion, this is a bug, because the current implementation is inconsistent. Either

The REST repository and resource are implemented like the latter, so the JSON schema should be as well. When looking at the code, it looks like this case was simply forgotten

spring-projects-issues commented 4 years ago

Christoph Huber commented

This is still not fixed and my pull request remained open and uncommented. I therefore use my forked repository in my projects. If someone needs this fix too, fetch the release branch [original-version]-FORK, e.g. https://github.com/huberchrigu/spring-data-rest/tree/release/3.4.1-FORK

spring-projects-issues commented 4 years ago

Oliver Drotbohm commented

Sorry for long delay in response. I just took a stab at this and it's not as easy as it seems to be. The current implementation is in place deliberately as commented on in DATAREST-690: for associations, singular or plural, we expose a unique URL to manage that and don't render the property directly in the responses at all. I.e. the fact, that the property is rendered us URI in the schema is an indicator that the client needs to look up the property in the _links clause to obtain the value of that property.

I guess the confusion stems from the question what the JSON Schema actually describes: the structure of the payload for PUT, POST, PATCH requests or the structure returned by GET requests. For representations containing associations to other resources, that is not the same thing fo the reasons mentioned above. Our current arrangement implements the latter of the two scenarios and I don't think we can simply change that as it would break clients that have worked with those assumptions until now

spring-projects-issues commented 3 years ago

Christoph Huber commented

Thanks Oliver Drotbohm. I haven't seen it that way and it makes sense to keep it like it is

spring-projects-issues commented 3 years ago

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.