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

How do you include relationships when mixing the JSON API and Rest serializers? #1087

Open
agentdon opened this issue May 22, 2023 · 3 comments

Comments

@agentdon
Copy link

agentdon commented May 22, 2023

Our app currently uses REST and we're working to gradually migrate to JSON API. Consequently, there are scenarios where we need to include a relationship in a JSON API request for an object whose serializer is a REST serializer. For example:

{
  serializers: {
    someJsonAPiObject: JSONAPISerializer,
    someRestObject: RestSerializer,
  },
  models: {
    someJsonApiObject: {
      someRestObjects: hasMany(),
    }
  }
}

Including the someRestObjects relationship for the someJsonApiObject doesn't work and simply just results in a missing field. If I change the serializer for someRestObject to the JSONAPISerializer, then everything works as expected. But this isn't a feasible option as we want to be able to gradually migrate endpoints to JSON API one a at time. I tried playing around with every combination of configurations that I couldn't think of, but nothing seemed to work. Any ideas on how to tackle this?

@VictorPulzz
Copy link

VictorPulzz commented Sep 15, 2023

@agentdon But my problem is that relations generally don’t arrive in the get response, do you know what the problem could be?

import { faker } from '@faker-js/faker';
import { belongsTo, createServer, Factory, Model } from 'miragejs';
import { ModelDefinition } from 'miragejs/-types';

import { TaskModel } from '~/entities/Task';
import { UserModel } from '~/entities/User';

export const userFactory = Factory.extend<UserModel>({
  id(i) {
    return i;
  },
  firstName() {
    return faker.person.firstName();
  },
  lastName() {
    return faker.person.lastName();
  },
  email() {
    return faker.internet.email({
      firstName: faker.person.firstName(),
      lastName: faker.person.lastName(),
    });
  },
  address() {
    return faker.location.country();
  },
  dob() {
    return faker.date.birthdate({ min: 18, max: 65, mode: 'age' }).toString();
  },
  avatar() {
    return faker.internet.avatar();
  },
});

export const taskFactory = Factory.extend<TaskModel>({
  id(i) {
    return i;
  },
  description() {
    return faker.lorem.paragraph(4);
  },
  createdAt() {
    return faker.date.recent().toString();
  },
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  afterCreate(task, server) {
    task.update({
      user: server.create('user'),
    });
  },
});

const UserDefModel: ModelDefinition<UserModel> = Model.extend({});
const TaskDefModel: ModelDefinition<TaskModel> = Model.extend({
  user: belongsTo(),
});

export function startMockServer() {
  createServer({
    namespace: 'api',
    models: {
      user: UserDefModel,
      task: TaskDefModel,
    },
    factories: {
      user: userFactory,
      task: taskFactory,
    },
    seeds(server) {
      server.createList('task', 100);
    },
    routes() {
      this.get(`/tasks`);
    },
  });
}

Response from console:
image

@cah-brian-gantzler
Copy link
Collaborator

@agentdon JsonAPI is an entire container, I would assume that once you start a JsonApi container, what would a none JsonApi object even look like within that container. Just given the spec, I dont think that would work. I understand wanting to do it gradually but I would think you would have to do it response by response (everything in the response) rather than a table by table thing.

@VictorPulzz I havent used factories much, but did you confirm that the afterCreate is being called and the user is being added to tasks. I would put a debugger in the seeds after server.createList and inspect the mirage DB. I think it would be server.schema.tasks.all(). I would do the same for users and if there were any created. server.schema.users.add()

@agentdon
Copy link
Author

@agentdon JsonAPI is an entire container, I would assume that once you start a JsonApi container, what would a none JsonApi object even look like within that container. Just given the spec, I dont think that would work. I understand wanting to do it gradually but I would think you would have to do it response by response (everything in the response) rather than a table by table thing.

Got it. That was the route that we wound up taking. Thanks for weighing in!

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

3 participants