首页 > 解决方案 > Remove null results from a array that can contain nullable values in GraphQL

问题描述

I have a query in my app that works but response is little ugly, there is probably two ways to solve this:

  1. Write resolver differently
  2. Clean response from null values

Here is resolver:

 t.list.field('manyDevices', {
      type: 'Device',
      description: 'Get list of devices belonging to user',
      args: {
        input: nonNull(deviceIdentifierInput.asArg()),
      },
      resolve: async (_, { input: { id } }, { prisma }) => {
        return await prisma.device.findMany({ where: { userId: id } });
      },
    });

This resolver looks for all devices with provided id. Id can be mine and also can be from a some other user. Devices can be public and private, and I don't want to receive private devices except if they are mine.

const isDevicePublic = rule({ cache: 'strict' })(
  async ({ isPublic }: Device) => {
    if (!isPublic) {
      return permissionErrors.noPermission;
    }
    return true;
  },
);

const isDeviceOwner = rule({ cache: 'strict' })(
  async ({ userId }: Device, _, { user }: Context) => {
    assertValue(user, permissionErrors.noAuthentication);
    if (userId !== user.id) {
      return permissionErrors.noPermission;
    }
    return true;
  },
);

These are rules that I place on my schema with graphql-shield library and it works. There is just one problem, if a user have a private device it will be listed in response array as null and graphql-shield will throw error, so response can look like this:

{
  "errors": [
    {
      "message": "You have no permission to access this resource",
      "locations": [
        {
          "line": 3,
          "column": 5
        }
      ],
      "path": [
        "manyDevices",
        0,
        "name"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "stacktrace": [
            "Error: You have no permission to access this resource",
            "    at Rule.resolve (/workspace/node_modules/graphql-shield/dist/rules.js:33:24)",
            "    at runMicrotasks (<anonymous>)",
            "    at processTicksAndRejections (internal/process/task_queues.js:93:5)",
            "    at async Promise.all (index 0)"
          ]
        }
      }
    }
  ],
  "data": {
    "manyDevices": [
      null,
      {
        "name": "device-01"
      }
    ]
  }
}

So there is one fetched device and other that is private that throws this error, can I somehow remove null and error response or should I filter them out in resolver?

标签: graphql

解决方案


推荐阅读