Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OneToMany Relation with direct links [DATAREST-682] #1055

Open
spring-projects-issues opened this issue Sep 23, 2015 · 3 comments
Open

OneToMany Relation with direct links [DATAREST-682] #1055

spring-projects-issues opened this issue Sep 23, 2015 · 3 comments

Comments

@spring-projects-issues
Copy link

@spring-projects-issues spring-projects-issues commented Sep 23, 2015

Thomas Letsch opened DATAREST-682 and commented

Normally SDR creates a separate URI for a one-to-many relation. This is quite right, when the relation itself provides useful additional properties.
But this comes at a cost:
To query a list of resources with related resources, you have to do additional n queries to get the related resources as well. Now if you like to use some kind of caching for the many side of the relation, this is not possible.
Of course you can work with projections. The downside of this is that you have to use different entities in list and detail queries. Which makes things like e.g. inline editing quite hard.

The corresponding class is IMHO the LinkCollectingAssociationHandler, which is manually instanciated inside the PersistentEntityJackson2Module. Making a adjustment quite hard.
Also it differs from POST / PUT where you put the URI to the other resource directly into the links section.

It would be a great improvement to have a possibility to switch between having the relationship link pointing to its own URI or pointing to a root resource URI.
Whats your opinion?

Here some links I discovered:
http://stackoverflow.com/questions/15886897/how-do-i-avoid-n1-queries-with-spring-data-rest
http://stackoverflow.com/questions/24570279/canonical-links-with-spring-hateoas
http://stackoverflow.com/questions/25143193/hateoas-restfull-entity-relation-broken

Thanks,
Thomas


Affects: 2.4 GA (Gosling)

Reference URL: http://stackoverflow.com/questions/15886897/how-do-i-avoid-n1-queries-with-spring-data-rest

1 votes, 3 watchers

@spring-projects-issues
Copy link
Author

@spring-projects-issues spring-projects-issues commented Sep 4, 2018

Guram Savinov commented

There is a gist which would make it possible to have canonical links of related resources using projections
https://gist.github.com/olivergierke/bd204f35c98b5e2b8d5e

I think that would be a useful feature.

For now it's possible to add links to related resources manually as described here: https://stackoverflow.com/a/15902210/2017801

@spring-projects-issues
Copy link
Author

@spring-projects-issues spring-projects-issues commented Sep 4, 2018

Oliver Drotbohm commented

First of all, there's already pretty extensive support for including information about the related resources with excerpt projections, which also contain the canonical links of the related resources. Plus, if you're only interested in the collection associations of the resource: that's already exposed under a URI, i.e. that's a single HHTP request to get those. Also, it brings the advantage of being able to properly manipulate that relationship.

Removing the links to the association resources and rather point to the association targets feels weird as it raises the question how you'd manage the relationship in the first place then?

Guram Savinov – What you see in the Gist is a demo of the excerpt projection feature we have had since the Evans release, see DATAREST-317

@spring-projects-issues
Copy link
Author

@spring-projects-issues spring-projects-issues commented Sep 4, 2018

Guram Savinov commented

Maybe I didn't get what you mean, but projections return indirect links of related resources, for example:

class User {
    public String name;
    public Book book;
}

class Book {
    public String title;
    public String author;
}

@Projection(name = "userProjection", types = User.class)
public interface UserProjection {
    Book getBook();
}

Request to authors with UserProjection returns:

{
  "_embedded" : {
    "users" : [ {
      "book" : {
        "title" : "title1",
        "author" : "author1"
      },
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/api/users/1"
        },
        "user" : {
          "href" : "http://localhost:8080/api/users/1"
        },
        "book" : {
          "href" : "http://localhost:8080/api/users/1/book"
        }
      }
    }
  }
}

 As you can see, there is no _links of related book entity with canonical link: http://localhost:8080/api/books/1

To force SDR to add canonical link of Book entity we have to apply one more additional projection to Book itself.

 

@Projection(name = "bookProjection", types = Book.class)
public interface BookProjection {
    String getTitle();
    String getAuthor();
}

Only after that SDR starts to include canonical link to related Book resource:

{
  "_embedded" : {
    "users" : [ {
      "book" : {
        "title" : "title1",
        "author" : "author1",
        "_links": {
          "self": {
            "href": "http://localhost:8080/api/books/1{?projection}",
            "templated": true
          }
        }
      },
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/api/users/1"
        },
        "user" : {
          "href" : "http://localhost:8080/api/users/1"
        },
        "book" : {
          "href" : "http://localhost:8080/api/users/1/book"
        }
      }
    }
  }
}

We have to create and use projections for each related resource to get canonical links, quite strange behaviour, isn't it?

Besides that href ends with '{?projection}' postfix, to get pure self link we have to cut it off

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.