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

Ensure valid jsonapi when blank relationship #1930

Merged
merged 1 commit into from
Sep 19, 2016

Conversation

richmolj
Copy link
Contributor

Purpose

If you specify include_data false, and do not have any links for this
relationship, we would output something like:

{ relationships: { comments: {} } }

This is not valid jsonapi.

Changes

We will now render

{ relationships: { comments: { meta: {} } } }

Caveats

N/A

Related GitHub issues

#1797

Additional helpful information

Relevant jsonapi spec: http://jsonapi.org/format/#document-resource-object-relationships

@mention-bot
Copy link

@richmolj, thanks for your PR! By analyzing the annotation information on this pull request, we identified @groyoh, @bf4 and @remear to be potential reviewers

@@ -34,6 +34,11 @@ def as_json

private

def ensure_valid!(json)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this the JSON API recommended way to deal with this problem? seems funky

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We definitely need one of data, links, or meta according to the spec. We definitely don't have the first (remember empty data is incorrect here). Empty links also seems invalid, so that's a no go. The section on meta seems to indicate empty meta is valid. So If a better alternative exists, I don't know it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fair enough

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remember empty data is incorrect here

I don't remember. Why can't it be data: null, or data: []?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@remear it's the difference between "we're not saying anything about this relationship one way or the other" versus "this relationship is blank".

For instance, let's say you use ember-data and post belongs to author, both objects already loaded into memory. A subsequent GET to the API that returns author: { data: null } will blow away post.author. Omitting the data key does not.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does it need to be a separate endpoint? What if it's an existing one with a parameter? Why not just make an an endpoint for fetching that data? What about a relationships endpoint for that resource? The answers to those questions are better determined by the application and API design.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does it need to be a separate endpoint? What if it's an existing one with a parameter?

Then you'd be linking to a collection of posts, instead of a collection of comments, which is invalid (even if the comments are sideloaded via an ?include parameter).

Why not just make an an endpoint for fetching that data?

Because I'd rather not code and test a completely unused endpoint just because relationships: { comments: {} } is not valid jsonapi.

What about a relationships endpoint for that resource?

Not needed, this relationship is only fetched by my web application when sideloading.

The answers to those questions are better determined by the application and API design.

Agree. With the above answers, I am saying it is a reasonable API design to not have a separate endpoint, which means no links can be present.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The schema is the only thing we have against which to actually validate documents. The schema must be fixed before changes like this can be merged.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merging this PR would still validate against the existing schema 😄

But I am fine with waiting, as long as we verify there are no other concerns.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should wait. Schema ambiguity is dangerous territory.

@richmolj
Copy link
Contributor Author

@kevintyll brought this up. I'm making this change independent of #1797 since the situation already exists in master.

@NullVoxPopuli
Copy link
Contributor

In all this discussion, I've forgotten the root of the issue. @richmolj can you summarize the problem trying to be solved here?

@richmolj
Copy link
Contributor Author

@NullVoxPopuli is there something missing from the PR description I could add? The problem is that AMS is outputting invalid jsonapi. No actual errors thrown or anything like that within AMS, but errors might be thrown by clients consuming this json and expecting a compliant structure.

Props for adding the word root to as many issues as possible 😆

@NullVoxPopuli
Copy link
Contributor

Ok, cool. So this is just about validating against JSON API's schema. So, lets all revisit this when the schema gets updated. :-)

@richmolj
Copy link
Contributor Author

Cool, here is a PR to fix the schema: json-api/json-api#1094

@NullVoxPopuli
Copy link
Contributor

Ok, now that that is merged, @richmolj what does the difference between meta: {} and links: {} mean to you?

@richmolj
Copy link
Contributor Author

@NullVoxPopuli I have a hunch links: {} is invalid. I've opened an issue to get clarification.

To answer your question, empty links is meaningless to me, which is why I think it is invalid. Empty meta tells me "I'm not saying anything about this relationship one way or the other", which is the intent of this PR.

If links: {} is valid, I'd be happy to accept that as a solution, though I find meta: {} more sensible, personally.

@NullVoxPopuli
Copy link
Contributor

I guess one way to think about it that if links is empty that says: there is no way to get any information about this relationship. Meaning that the only way to even get that relationship is through the endpoint you just hit.

meta: {} just feels ambiguous to me.

idk.

@remear thoughts?

@richmolj
Copy link
Contributor Author

richmolj commented Sep 19, 2016

Honestly, I think this is a jsonapi issue, not an AMS issue. the jsonapi maintainers have told us empty meta is preferable.

I don't care too much one way or the other as long as it's valid, but suggest we try to convince them if we want to go in a different direction. Seems like an area AMS and jsonapi should be on the same page.

@NullVoxPopuli
Copy link
Contributor

well, if JSON API people say that it's preferable, then I guess that's what we go with.

Copy link
Contributor

@NullVoxPopuli NullVoxPopuli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing out github's review feature. Pretty handy. I know how to use it now!

@@ -25,7 +25,7 @@ def as_json
meta = meta_for(association)
hash[:meta] = meta if meta
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now for code review. :-)

I don't like that ensure_valid! just adds a blank meta. The method name is misleading.
Since the logic is so simple, can you add that logic to this method?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thought was this is a placeholder for other things we might want to do, but sure no worries.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to have too many placeholders right now. Overall, we're trying to simplify AMS. :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've force pushed this change. I still find the updated code less descriptive, but my salience is very low.

@richmolj
Copy link
Contributor Author

@NullVoxPopuli turns out links: {} is valid FWIW.

@NullVoxPopuli
Copy link
Contributor

I saw that. :-)

If you specify include_data false, and do not have any links for this
relationship, we would output something like:

`{ relationships: { comments: {} } }`

This is not valid jsonapi. We will now render

`{ relationships: { comments: { meta: {} } } }`

Instead.

Relevant jsonapi spec: http://jsonapi.org/format/#document-resource-object-relationships
@NullVoxPopuli NullVoxPopuli merged commit a77dfda into rails-api:master Sep 19, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants