-
Notifications
You must be signed in to change notification settings - Fork 184
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
Relationships fall apart in many scenarios #176
Comments
Thanks for taking the time to investigate all this stuff. I am ok with improving the relationships stuff but let me first explain a few of motivations behind some of the design choices. I started this project to give a familiar interface for building json-api requests (and started it way pre-1.0). As such, some of the initial decisions were based upon the initial thinking of jsonapi.org. Additionally, I manage 2 branches of this project - master which tracks the 1.0 spec and and 0.x branch which is the version my company uses for our internal api format. I tried to make the 1.0 gem version modular to be able to support my 0.x format in the future. One thing that I want to impress is that services and API should abstract away most of the business logic otherwise we're coupling our API with a single client codebase. We don't want our APIs to just be a database access layer over http/rest/json. FindThe first point about ScopesI don't mind trying to extend the scope interface but I don't think it's actually necessary. One of the pitfalls of building services in a SOA environment, is business logic creeping into the clients. The provided scopes map directly to the types of query building available in the jsonapi specification. In a roundabout way, it somewhat protects you from building logic into your client. I'm fine with trying to make it easier to add scopes. RelationshipsI agree that the relationship stuff is not the best. On of the features of jsonapi is that it's supposed to be somewhat of a hypermedia interface - that you can browse the relationships without previous knowledge of the structure of the endpoints. At the same time, there is some general knowledge about what base endpoints exist. Internally, we don't use relationships or nested routes. This is because you have to know your parent's id in order to access the resource. Finding stuff by parent id could be implemented as a filter param on the resource. This does assume that you control the api source. Because we don't use relationships, I don't have the perspective of using the relationships stuff. ConclusionI would definitely appreciate work on the relationships stuff. I would make sure it's not required as I don't think it should be required. I haven't actually looked into PassiveRecord. I definitely welcome collaboration on this project. |
@coreyward @chingor13 Has any work been put into creating more robust relationship querying interface? |
@natemacinnes I haven't done any work on it since this post was made. |
@coreyward okay, thanks for the update. @chingor13 I am interested in helping out if I can. The project I am currently working on requires creating objects with nested relationships. |
@coreyward Thanks for the link to PassiveRecord. It set me thinking about using ActiveModel+PassiveRecord+Faraday to write my own JSON-API client. I wonder how hard can it be? |
After a few weeks of working with JsonApiClient, I've found myself resorting to acrobatics to do straightforward things more often than I'd like. Here are a few examples that illustrate what I've run into. For these examples, consider the following simple schema:
Starting off simple: finding an order by ID.
The user needs to call
first
, despite the path establishing that there is no spec-compliant response that can contain more than a single resource:Compare to how PassiveRecord handles this:
To get a little more complex with finders…
Chaining is great, especially when we can define scopes, a la ActiveRecord. Unfortunately, the following is required for this to work:
Yikes.
What about assigning a relationship?
Here we use a simple setter to assign a pre-defined relationship (via
has_one
andbelongs_to
). Unfortunately, it doesn't do at all what's expected.While the
DynamicAttributes
module handles the assignment methods appropriately, it isn't extended at all by relationship-aware classes that use it as a mixin. As a result, the getter method accesses the relationship, which remains nil despite the user's efforts.Removing a resource
As a final example, when attempting to delete an associated resource as part of a compound document retrieval, the relationship traversal shortcomings become more clear:
In this case,
shipment
requiresorder_id
to build the path, but the relationship linker doesn't provide a mechanism for upward traversal, and the JSON API spec doesn't have the parent ID established in the child attributes.I think JsonApiClient does some great things, and I'm glad it's available, but I think the above examples are a fair representation of a shortcoming that can be addressed.
I'm open to helping out in this area, provided there's interest. I considered plugging some of these gaps with smaller changes, but the
Resource.relationship_linker
object has a significant surface area, and the underlying implementation seems coupled with the JSON API data representation, making it hard to move on.In closing, I have two (and a half) questions:
Thanks for reading through to the end!
The text was updated successfully, but these errors were encountered: