Cauen / prisma-generator-pothos-codegen

The fastest way to create a fully customizable CRUD Graphql API from Prisma Schema.
https://www.npmjs.com/package/prisma-generator-pothos-codegen
95 stars 18 forks source link

subscriptions support #17

Closed useafterfree closed 1 year ago

useafterfree commented 1 year ago

Would it be possible to generate subscriptions in the the generators?

I am using: https://pothos-graphql.dev/docs/plugins/smart-subscriptions#creating-a-smart-subscription

I am looking for suggestions, also. Not sure if I need to tweak the generated output by hand or not?

Cauen commented 1 year ago

Hi @useafterfree

You can use this library with Pothos plugins like this:

import { builder } from "../../builder";
import { findFirstOrderQueryObject } from "../../__generated__/Order";

export const findFirstOrderTest = builder.queryFields((t) => {
  const field = findFirstOrderQueryObject(t);
  return {
    findFirstOrderTest: t.prismaField({
      ...field,
      args: {
        testParam: t.arg({ type: "String", required: false }),
      },
      resolve: async (...args) => {
        const [include, root, { testParam }, { response, prisma }, info] = args;
        if (testParam === "123") throw new Error("Invalid");
        return field.resolve(...args);
      },
      smartSubscription: true, 
      subscribe: (subscriptions) => subscriptions.register(`DATABASE-UPDATED-ORDER`)
    }),
  };
});

And then in prisma Middleware you can trigger pubsub updates like this:

prisma.$use(async (params, next) => {
  const { action, args, dataPath, model } = params

  const result = await next(params)
  if (
    params.action === 'create' ||
    params.action === 'update' ||
    params.action === 'delete' ||
    params.action === 'deleteMany' ||
    params.action === 'updateMany' ||
    params.action === 'createMany'
  ) {
    log(module)(`🚀 ${params.action} ${params.model}`)
    pubsub.publish('DATABASE-UPDATED-'+model, {})
  }
  // See results here
  return result
})

Inside builder you need to configure

...
import SmartSubscriptionsPlugin, { subscribeOptionsFromIterator } from '@pothos/plugin-smart-subscriptions';

export const builder = new SchemaBuilder<{
  Context: Context,
  PrismaTypes: PrismaTypes,
  Scalars: Scalars<Prisma.Decimal, Prisma.InputJsonValue | null, Prisma.InputJsonValue>,
  smartSubscriptions: {
    debounceDelay: number | null;
    subscribe: (
      name: string,
      context: Context,
      cb: (err: unknown, data?: unknown) => void,
    ) => Promise<void> | void;
    unsubscribe: (name: string, context: Context) => Promise<void> | void;
  },
}>({
  plugins: [PrismaPlugin, SmartSubscriptionsPlugin],
  prisma: {
    client: prisma,
  },
  smartSubscriptions: {
    ...subscribeOptionsFromIterator((name, { pubsub }) => {
      return pubsub.asyncIterator(name);
    }),
  },
});

And pothos auto creates a subscription for findFirstOrderTest query

Cauen commented 1 year ago

@useafterfree

In the new 0.5.1 version you can apply plugins to all crud resolvers

Please, see example

I hope it helps

useafterfree commented 1 year ago

omg, thanks so much! I applied your example and got: Cannot read properties of undefined (reading 'Symbol(Pothos.contextCache)') which I am not sure how to address.

Cauen commented 1 year ago

Can you please share a minimal, reproducible example? in a Github repo?

useafterfree commented 1 year ago

minimal, reproducible example?

Of course. I made a version here. You can run by using: yarn run example or yarn run dev:debug which both run example.ts

Cauen commented 1 year ago

@useafterfree

New Apollo v4

Strange that I couldn't make Pothos work with the new Apollo Subscriptions. I tested it with another Schema (ok), and when I switch to Schema with Pothos, it gives an error ❌ (I've opened a issue)...

Working with Apollo v2

Months ago I had tried to configure with an old version of apollo and it had worked fine 💹 https://github.com/Cauen/apollo-subscriptions-pothos/tree/old-version-apollo This example generates automatic subscriptions for all queries with autocrud.

Yoga?

I tested pothos example with Yoga, and working fine... 💹


Let's wait to see if the author of Pothos can help with something in this

Cauen commented 1 year ago

@useafterfree Updated example now working

https://github.com/Cauen/apollo-subscriptions-pothos

useafterfree commented 1 year ago

Thank you, let me take a look!

useafterfree commented 1 year ago

After adding the context to useServer it worked perfectly, thank you so much!