-
Notifications
You must be signed in to change notification settings - Fork 65
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
Encoding Relationships #55
Comments
Your links belongs not to the resource but to the document (side question for you what do you think it would belong to if Anyways you can add such links with a second parameter of encode method. For your case it will be $links = [
'self' => new Link('/articles/1/relationships/author'),
'related' => new Link('/articles/1/author'),
]; However most likely you want
In this case you need to add them in If you have any further questions please don't hesitate to ask. |
The problem is the Effectively this endpoint is returning a Relationship Object that is in the root document. I've tried providing a As there's an Also, would it not be possible for this to be done using the SchemaProvider? In the example above, effectively the endpoint is returning the So effectively what you want to be able to do is something like this on the encoder interface: public function relationship($resource, $relationship, $meta = null, EncodingParametersInterface $parameters = null) which in the example would be called as: $encoder->relationship($article, 'author'); |
This post might be completely irrelevant to your question but what I think while reading you second comment
I've got same set of questions what is
That's likely the same question applied to similar object
A real example might help to understand what you want to achieve. |
@neomerx It's been evening here (York, UK) and I've been out tonight! Will be able to write more tomorrow if needed, but the endpoint I'm talking about is fully documented in the JSON API spec. See http://jsonapi.org/format/#fetching-relationships
That section of the spec has examples in it. |
I got it. You have to add handler to your controller that reads author/comments from data storage and returns encoded result. class ArticlesController
{
public function getRelationship($articleId, $relationshipName)
{
...
$author = ...;
$links = ???
$this->getResponse($author, 200, $links);
}
} The question is what is the best way to create $author doesn't contain information about response links and that it actually come from a relation to You know you're in $links = [
'self' => new Link("/articles/$articleId/relationships/$relationshipName"),
]; Another option is to automate
Thus such generation function might look like createRelationshipLink(Article::class, $articleId, $relationshipName); What are your thoughts on that? |
I really feel this totally has to be automated, because otherwise I'm having to program a lot of logic into a controller that is actually contained within the relevant schema providers. It's a duplication of code, which means I'll have two places to update stuff. For this request: GET /articles/1/relationships/author HTTP/1.1
Accept: application/vnd.api+json The minimum response is: HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
"data": {
"type": "people",
"id": "12"
}
} (I've intentionally left out the links, as they are not compulsory whereas the data is.) In the controller, I get the article from the data store, and then get the author from that. I now have to construct a resource identifier for the response, for which I need to know in the controller that the Also, if I'm using a single instance of an Encoder across my whole application, the other thing I'll need to do in the controller is return a response that is encoded consistently with every other endpoint in the API. That information is held in the EncoderOptions that the Encoder is created with. So therefore it definitely makes sense to me to use the encoder to generate the JSON response. So the result of this, is I need the encoder to generate the entire JSON response, both Another thing is the spec says that the response at this endpoint needs to match the relationship object contained within the resource object to which it relates.
So if my {
"type": "articles",
"id": "1",
"attributes": {
"title": "Rails is Omakase"
},
"relationships": {
"author": {
"links": {
"self": "/articles/1/relationships/author",
"related": "/articles/1/author"
},
"data": { "type": "people", "id": "9" }
}
}
} Then the response to the So all I need to do in the controller is get the article based on the id, then asked the encoder to encode the |
I've got an idea to split this task into 2 parts
I've added a non-working prototype ( $encoder = ...;
$encoder->withRelationshipLink(
DocumentInterface::KEYWORD_SELF,
Article::class,
$articleId,
$relationshipName
)->encode(...); Yes, I would appreciate your help with it. I'm working on CORS support at the moment (which might be useful for you as well). |
@lindyhopchris I can do first part quickly however the second part looks more complicated and I can start working on it in a few days |
@lindyhopchris I've added prototype for second part. It might be not as difficult as I thought in the first place. |
Yeah, the The only thing I'd question is the In the draft So for the {
"data": {
"type": "people",
"id": 1
}
} but this would not be correct: {
"data": {
"type": "people",
"id": 1,
"attributes": {
"firstName": "Foo",
"surname": "Bar"
}
} |
PS: Working on it in the next few days is not a problem! Not expecting this to be solved straight away. We're currently prototyping a JSON-API in an application that's not due for immediate release, so I'm not working against an immediate deadline. |
I think of replacing $encoder = ...;
$encoder->withLinks(...)->withMeta(..)->withSomeBeer(...)->encode($data, $options);
You are right for this particular method it's not needed. The method can send the right value to one of the chaining methods.
It will be using the Schema used on Anyways feel free to post a PR to |
The JSON API spec says that a relationship endpoint returns the resource linkage, not the resource object. For our This request (the GET /api/article/1/author Returns the resource object: {
"data": {
"type": "people",
"id": 1,
"attributes": {
"firstName": "Foo",
"surname": "Bar"
}
}
} From the spec:
Whereas this request (the GET /api/article/1/relationships/author Returns the resource linkage: {
"data": {
"type": "people",
"id": 1
}
}
Not meaning to be a pain about this, but there is definitely a distinction between the two! Your library is a great implementation, adding in this ability to encode the relationship resource linkage will increase its coverage of the spec. |
@lindyhopchris Ok thanks for your help with the spec.
|
@lindyhopchris I've partly solved the issue. How relationship links could be added you can see in this example. As you can see you can encode relationships as this $encoder->withRelationshipRelatedLink($post, $relationshipName)->encodeData($post->{$relationshipName}); Are you OK with this approach or like The only problem
Would be nice to have some feedback from you. |
@lindyhopchris I've finished this enhancement (some samples from tests here). The code is in That's the code snippet for encoding relationships $encoder = ...;
$resource = ...;
$relationshipName = '...';
$encoder
->withRelationshipSelfLink($resource, $relationshipName)
->withRelationshipRelatedLink($resource, $relationshipName)
->encodeIdentifiers($resource->{$relationshipName}); |
Looks good. I'll be able to try it out tomorrow at work (sorry, didn't get a chance to do it today). From the sample tests, it looks like it'll work nicely. |
@lindyhopchris I would be happy to hear your opinion on paging links generation enhancement #61 |
@neomerx this all works a treat. Thanks for adding it in. :-) |
Hi,
Just wondering how relationship endpoints are meant to be encoded? The encoder interface doesn't seem to have a method for encoding relationships, and I can't find any mention in your wiki about it.
The example instance from the JSON-API spec would be:
The text was updated successfully, but these errors were encountered: