prisma / p1-to-p2-upgrade-path-feedback

4 stars 1 forks source link

Unable to migrate evented architecture #7

Open LawJolla opened 4 years ago

LawJolla commented 4 years ago

Your Prisma 1 stack

What are you building with Prisma?

Two Nexus servers, customer and admin. Car dealership platform with a sales front end and business/admin backend

Which version of Prisma 1 are you running?

1.3.4

How do you access your Prisma server?

prisma-client-lib

Are you currently using nexus-prisma (with Prisma 1)?

Yes

How many Prisma services are you running on your production Prisma server?

Two, prod and dev

Which database (incl. version) do you use?

PostgreSQL 10

Where is your Prisma server hosted?

AWS Fargate

Where is your database hosted?

AWS/RDS

Where is your API server hosted?

Heroku

Is there anything else that's worth mentioning about your stack?

Search with Algolia

Your upgrade plans

What's your preferred upgrade strategy?

Do you want to use the new Nexus Framework when you upgrade?

Yes

When do you want to upgrade?

Do you have any remaining questions or comments?

I'm being hard hit by the lack of subscriptions. I listen to Prisma node changes to rebuild Algolia. This allows any changes to the node, either by the customer or admin servers, trigger an update without polluting every resolver where the node could possibly change

E.g.

...
httpServer.listen(() => {
 ...
   if (process.env.NODE_ENV === `production`) {
      listenToVehicleChanges()
    }
}
...
const listenToVehicleChanges = async () => {
  const subscription = await prisma.$subscribe.vehicle()
  handleAlgoliaVehicleSubscription(subscription, prisma)
}
...
export const handleAlgoliaVehicleSubscription = async (
  subscription,
  prisma
) => {
  try {
    const result = await subscription.next()
    if (!result.value || !result.value.node) {
      handleAlgoliaVehicleSubscription(subscription, prisma)
    } else {
      const obj = await algoliaUpdateVehicle({
        prisma,
        vehicleId: result.value.node.id
      })
      index.addObjects([obj], (err, obj2) => {
        if (err) throw new Error(`[algoliaUpdateVehicle] ${e.message}`)
      })
      if (!result.done) {
        handleAlgoliaVehicleSubscription(subscription, prisma)
      } else {
        console.log("vehicle sub done")
      }
    }
  } catch (e) {
    throw new Error(`[handleAlgoliaVehicleSubscription] ${e.message}`)
  }
}
abhiaiyer91 commented 4 years ago

I think in Prisma 2 you might be able to get away with a middleware

When the client makes an update to the Vehicle model, after the update you could do your algolia things based on the model/action.

async function someMiddleware(
    params: MiddlewareParams,
    next: (params: MiddlewareParams) => Promise<any>
  ) {

  const result = await next(params);

  if (params.model === 'Vehicle' && params.action === 'update') {
    // update algolia
    // addObjects
  }

  return result

}
LawJolla commented 4 years ago

I think in Prisma 2 you might be able to get away with a middleware

When the client makes an update to the Vehicle model, after the update you could do your algolia things based on the model/action.

async function someMiddleware(
    params: MiddlewareParams,
    next: (params: MiddlewareParams) => Promise<any>
  ) {

  const result = await next(params);

  if (params.model === 'Vehicle' && params.action === 'update') {
    // update algolia
    // addObjects
  }

  return result

}

Yes! I think this could work. I'm already running a mono repo, so putting a middleware function into a shared-server package and putting it into both server Prisma middlewares isn't complicated.

As soon as Migrate is ready, I will give this a try. Great solution and work!