crnk-framework
crnk-framework copied to clipboard
Relationships break when upgrading from 2.10 to 2.11
Attached is an example project with three servers - ItemServer, OwnerServer, and Coordinator. crnk-upgrade-issue.zip
Coordinator is the client facing part and it calls down to ItemServer and OwnerServer.
Request to Coordinator http://127.0.0.1:12010/item/2003/owner Response {"data":null} But should be {"data":{"id":"1003","type":"owner","attributes":{"name":"Frodo"},"links":{"self":"http://127.0.0.1:12010/owner/1003"}}}
Request to ItemSever http://127.0.0.1:12011/item-internal/2003 Response {"data":{"id":"2003","type":"item-internal","attributes":{"name":"The One Ring","ownerId":1003},"links":{"self":"http://127.0.0.1:12011/item-internal/2003"}}}
Request to OwnerServer http://127.0.0.1:12012/owner-internal/1003 Response {"data":{"id":"1003","type":"owner-internal","attributes":{"name":"Frodo"},"links":{"self":"http://127.0.0.1:12012/owner-internal/1003"}}}
Request to Coordinator http://127.0.0.1:12010/item/2003/ Response {"data":{"id":"2003","type":"item","attributes":{"name":"The One Ring"},"relationships":{"owner":{"links":{"self":"http://127.0.0.1:12010/item/2003/relationships/owner","related":"http://127.0.0.1:12010/item/2003/owner"}}},"links":{"self":"http://127.0.0.1:12010/item/2003"}}}
Request to Coordinator http://127.0.0.1:12010/owner/1003/ Response {"data":{"id":"1003","type":"owner","attributes":{"name":"Frodo"},"links":{"self":"http://127.0.0.1:12010/owner/1003"}}}
This seems to be where our QuerySpec gets borked https://github.com/crnk-project/crnk-framework/blob/master/crnk-core/src/main/java/io/crnk/core/repository/foward/strategy/ForwardingStrategyContext.java#L52
Upgrading to 3.1.20191113192440 doesn't help.
you see already the fix?
No. Is there a fix available?
I did not really manage to quite follow. the zip file does not contain any test cases. What is the expected and erroreous behavior? any exceptions? If you like you can also start a PR to add a test case for the given use case.
if you run the three servers and make this request to coordinator: http://127.0.0.1:12010/item/2003/owner
The response (using crnk 2.11 or higher) is {"data":null}
But it should be {"data":{"id":"1003","type":"owner","attributes":{"name":"Frodo"},"links":{"self":"http://127.0.0.1:12010/owner/1003"}}}
This seems to be where our QuerySpec gets borked https://github.com/crnk-project/crnk-framework/blob/master/crnk-core/src/main/java/io/crnk/core/repository/foward/strategy/ForwardingStrategyContext.java#L52
thank you for the details. I tried it out and set the break point at that place:

Here the owner field is backed by a ownerId field annotated with @JsonApiRelationId. Because it being null it correctly returns null.
Okay, so does that mean the older version (2.10) was letting us do the wrong thing? Also, when I hit http://127.0.0.1:12010/item/2003/ I get {"data":{"id":"2003","type":"item","attributes":{"name":"The One Ring"},"relationships":{"owner":{"links":{"self":"http://127.0.0.1:12010/item/2003/relationships/owner","related":"http://127.0.0.1:12010/item/2003/owner"}}},"links":{"self":"http://127.0.0.1:12010/item/2003"}}}
How come name=null in your trace?
I don't understand why we get all fields null in your trace. item 2003 is retrievable with http://127.0.0.1:12010/item/2003/
the semantics of @JsonApiId being null not giving a relationship is correct. Not sure what is up in 2.10. If I remember correctly, at that point in time there was a lot of work going on on relationships and @JsonApiRelationId was introduced at that point as well.
I did not see any setter for the fields to be filled up. But also did not investigate to closely.
Okay, so there are setters for the @JsonApiId fields. What I don't understand is why I can get an Item properly populated but when I try to get an Item/Owner, the Item has all its fields apart from id set to null which then means the Owner is then null. Seems the null issue happens before the attempt to resolve the relationship.
a bit more detail
I dug out the url used in
ResourceRepositoryStubImpl.findAll(QuerySpec querySpec)
and used it directly
calling
http://127.0.0.1:12011/item-internal?filter[item-internal][id][EQ]=2001&fields[item-internal]=id
returns
{"data":[{"id":"2001","type":"item-internal","links":{"self":"http://127.0.0.1:12011/item-internal/2001"}}]}
which hasn't got any of the attributes I see when I call
http://127.0.0.1:12011/item-internal/2001
and get
{"data":{"id":"2001","type":"item-internal","attributes":{"name":"Glass Slippers","ownerId":1001},"links":{"self":"http://127.0.0.1:12011/item-internal/2001"}}}
The problem appears to be the &fields[item-internal]=id
calling
http://127.0.0.1:12011/item-internal?filter[item-internal][id][EQ]=2001
returns
{"data":[{"id":"2001","type":"item-internal","attributes":{"name":"Glass Slippers","ownerId":1001},"links":{"self":"http://127.0.0.1:12011/item-internal/2001"}}]}
which would then have a non-null ownerId
I guess this is something we just have to live with and work out how to fix (or avoid) ourselves.