Skip to content

How to serialize relationship referencing an external resource? #412

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

Closed
jelhan opened this issue Aug 28, 2019 · 6 comments
Closed

How to serialize relationship referencing an external resource? #412

jelhan opened this issue Aug 28, 2019 · 6 comments

Comments

@jelhan
Copy link
Contributor

jelhan commented Aug 28, 2019

One of my models has a belongs-to relationship, which references a model managed by another microservice. I'm wondering how to include resource linkage data for that one? As it's a belongs-to relationship the services knows the ID. There is no need to request the other microservice and I like to avoid that one to prevent coupling.

Let me give an example to make it more clear. Lets assume I've a posts resource, which has a author relationship. The authors resources referenced are hold by another service.

The resource object for a post should look like this:

{
  "type": "posts",
  "id": "1",
  "relationships": {
    "author": {
      "data": {
        "type": "authors",
        "id": "2"
      }
    }
  }
}

I don't want to include the authors resource as a compound document.

I think I need to return the reference in getRelationships method of posts's schema. But how? I've noticed that neomerx/json-api includes a Neomerx\JsonApi\Schema\Identifier, which should serve this use case. But it's not available in v1 used by Laravel JSON API. Is there any other trick? If possible I would like to avoid creating a model for authors as it's not owned by this microservice.

@lindyhopchris
Copy link
Member

Yeah that's one of the reasons we need to upgrade the neomerx package, as it would solve this problem. See #411 - it's going to a complex journey doing the upgrade but I'm hoping to get it done between October and December this year.

In the meantime the only real work around is to make an instance of the PHP class of the external service (i.e. whatever class you'd get back if you did request it from the microservice) and construct it with only the id. Does that make sense of do I need to expand on that?

It's a limitation of this version of the neomerx package that it expects to have the object class for encoding, even if it's just an identifier. I raised it before 1.0 but was dismissed as not being a legit use-case... so was pleasantly surprised to see it make an appearance in version 3!!

@jelhan
Copy link
Contributor Author

jelhan commented Aug 28, 2019

Thanks for your quick response.

In the meantime the only real work around is to make an instance of the PHP class of the external service (i.e. whatever class you'd get back if you did request it from the microservice) and construct it with only the id.

If I understand you right, the quickest solution is creating an eloquent model and a JSON:API resource? After that my getRelationships method in the schema could use that:

getRelationships($post) {
  $author = new App\Post;
  $author->id = $post->author_id;

  return [
    "author" => [
       SELF::DATA => $author,
    ]
  ];
}

@lindyhopchris
Copy link
Member

Yes, that's right. But you'll need to check the client hasn't asked for the author to be included (using isset($includeRelationships['author']) - because otherwise when the author is serialized in the included part of the document, it will have null for all of its attributes.

@jelhan
Copy link
Contributor Author

jelhan commented Aug 29, 2019

But you'll need to check the client hasn't asked for the author to be included (using isset($includeRelationships['author']) - because otherwise when the author is serialized in the included part of the document, it will have null for all of its attributes.

That shouldn't be an issue unless I explicitly add author to $allowedIncludePaths, isn't it?

@lindyhopchris
Copy link
Member

Yes that's right - if it's not allowed, it's never going to be included so you wouldn't need to check.

@jelhan
Copy link
Contributor Author

jelhan commented Sep 17, 2019

The work-a-round discussed here is working fine. Thanks for your good support. Feel free to close this issue unless you want to keep it open until a more advanced solution is available. E.g. returning an instance of Neomerx\JsonApi\Schema\Identifier directly in schema.

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

No branches or pull requests

2 participants