crnk-project / crnk-framework

JSON API library for Java
Apache License 2.0
287 stars 154 forks source link

@JsonApiRelation for out of process resolvable endpoints #352

Open nickbuller opened 6 years ago

nickbuller commented 6 years ago

We are building a set of Micro Services where each service serves JsonAPI but a single service only knows the id of a related entity, currently @JsonApiRelation expects to be able to resolve the target of the relationship in process which is restrictive. What would be really nice is to define a @JsonApiRelation for the key only and some user defined method of discovery to produce a resolvable URI (and potentially still work when "included" is specified by the client). If this can be done with the current 2.7 release then please do point me into the right direction as I am blocked at the moment.

remmeier commented 6 years ago

what you can do this make use of CrnkClient and get with CrnkClient.getRepositoryForType the repositories for the various remove services from other micro services. If those are registered next to actual ones from the current micro-service, inclusions will work.

what needs to be checked however is the url computation. Ideally the entire Crnk engine would reuse the urls it obtained from CrnkClient from the remote repository. But I suspect somewhere along the way like DocumentMapper a small fix will become necessary.

nickbuller commented 6 years ago

Thanks for the reply, I will look into to this soon as currently we are composing the services inprocess to complete the POC of using Crnk.

On a totally unrelated topic, we have written two extensions to Crnk that: -

  1. Filter resources based on Spring Spel expressions
  2. Filter resource attributes based on Spring Spel expressions
remmeier commented 6 years ago

regarding microservices: let us setup an example in https://github.com/crnk-project/crnk-framework/tree/master/crnk-examples with two small applications work side-by-side. The question has already come up two, three times and an example would be overdue.

regarding security: Spel support would make a lot of sense to have in general. Maybe by leeting crnk-setup-spring provide an extension to crnk-security. In that regard it maybe good to dump it into a branch somewhere, even if it is not in a compiling/working state.

nickbuller commented 6 years ago

I will create a small project in my repo and send you link for the security stuff.

As for the MicroServices side. Having had a think, a really nice solution would be a generic ResourceRepositoryV2 say RemoteResourceRepositoryV2 that forwards requests to a remote using the CrnkClient as you recommend with some configuration i.e a collection of "types" (as per @JsonApiResource definition), this would mean that the "opposite" lookup should work.

remmeier commented 6 years ago

to some degree I hope we get around any extensions to crnk-core (like RemoteResourceRepositoryV2) to keep it as minimal as possible. Potentially the CrnkClient could be wrapped with a "MicroServiceModule" to make this pattern a bit more explicit.

nickbuller commented 6 years ago

Sounds totally fine, perhaps best to start with a sample app in git that expresses the interface the user would want, then work out how to implement... I can certainly do the sample.

remmeier commented 6 years ago

if you have time for that sample, would be great. You can create a fork or I can give you access to create a branch here then we both can work on it.

nickbuller commented 5 years ago

Hi, sorry for the long delay, I see that you have now created a microservices sample which I've used as a template, this goes some way to solving / showing an approach to resolving this. It would be good if you can create a branch and give me access. My goal is: -

So building on your sample, Task & Project...

My applications run in different VM's while both applications know the structure of the JPA entities for Task and Project. They do not know the structure of the other side’s JsonApi resources served to clients for these types (say TaskDto and ProjectDto as the types), more importantly should not know (e.g a property is added/removed).

So when serving a TaskDto to a client all the service know is the ProjectDto's identity (Long id). The code can easily create a WrappedRepository and forward requests to the service serving ProjectDto's as a pure Resource object, but I have no way of specifying/wrapping the Resource object returned from the repository that represents the TaskDto as a relation in the ProjectDto. Even if this can be done some magic would need to happen to support JsonApi included QuerySpecs.

So I am happy to put the changes on a branch (or give you access to a clone) where I can commit the usecase and we can fill in the gaps.

Unrelated, but I've also implemented annotations that allow the use of Spring Spel expressions on JsonApiResource that I will also add to the example for potential inclusion.