0

I'm playing with crnk trying to deduce the bits I cannot find in the docs. I will explain my problem on standard crnk example: https://github.com/crnk-project/crnk-framework/tree/master/crnk-integration-examples/spring-boot-example.

There is one-to-many relationship between projects and tasks (the other resources are not relevant). If I understand it correctly (the example uses apparently deprecated opposite @JsonApiRelation parameter) the owner of the relation is 1Task.project1. I now want to list resources filtered by some properties of their related resources. E.g. this works as expected (leaving some unimportant bits from the response):

GET http://127.0.0.1:8080/api/tasks?filter[project.id]=121

{
  "data" : [ {
    "id" : "1",
    "type" : "tasks",
    "links" : {
      "self" : "http://127.0.0.1:8080/api/tasks/1"
    },
    "attributes" : {
      "name" : "Create tasks",
      "description" : null
    },
    "relationships" : {
      "project" : {
        "data" : {
          "id" : "121",
          "type" : "projects"
        }
    }
  } ]
}

But filtering in the opposite direction is not possible:

GET http://127.0.0.1:8080/api/projects?filter[tasks.id]=1

{
  "data" : [ ]
}

Is this expected under the setup of the resources (see above link)? If yes what must be done so that filtering works in both directions?

1 Answers1

0

Currently this is something a repository has to handle, one way of doing it is to make getter/setter become bidirectional, so a Task.setProject will add itself to Project.tasks.

IMHO I think it is something that a repository should handle, rather than built-in something in the crnk-engine. From a REST perspective an POST/PATCH/DELETE of a resource should NOT touch related resources. Which would defer the reponsitiblity to the repository to make those look-ups. But maybe there is a possiblity to have some built-in support for in-memory handling. The issue comes up with in-memory repositories. In for example the JPA case, SQL takes care of it (which could also provide a path of providing a solution to this).

Remo Meier
  • 141
  • 2
  • You are probably right. Today I was digging deeper into the code and realized that the framework is designed in such a way that `repository.findAll` is responsible for the whole operation of fetching and filtering the data. And because in my example `projects` repository does not know about `tasks` at all I get empty result. – David Kubecka Nov 08 '19 at 17:19
  • Also confirming that with JPA repository it works as expected, e.g. between schedules and creators as in https://github.com/crnk-project/crnk-framework/tree/master/crnk-integration-examples/spring-boot-example. – David Kubecka Nov 08 '19 at 17:24
  • On the other hand I still think that the engine could handle the situation somehow because at first glance it seems very similar to the whole relationship handling which is currently configurable using `lookUp`, `@JsonApiRelationId` etc. E.g. something like "if there's filtering on the opposite side query the correspoding repository as well". Although I sense here it would conceptually be much more difficult than performing the inclusion since there you are only enriching the data whereas with filters the engine would really have to implement some kind of join on the repository level... – David Kubecka Nov 08 '19 at 17:29
  • 1
    And regarding "From a REST perspective an POST/PATCH/DELETE of a resource should NOT touch related resources.": I think that the whole bidirectionality concept somehow goes against REST because if you update the owning side of the relation, e.g. assign task to a project by POSTing to /tasks, the task will be also visible from the project resource. Or do you view the situation differently? – David Kubecka Nov 08 '19 at 17:34