Skip to content
This repository has been archived by the owner on Sep 2, 2022. It is now read-only.

Filters/where for on DELETED subscription don't work #3272

Closed
MaksimKlepikov opened this issue Oct 8, 2018 · 8 comments
Closed

Filters/where for on DELETED subscription don't work #3272

MaksimKlepikov opened this issue Oct 8, 2018 · 8 comments

Comments

@MaksimKlepikov
Copy link

Describe the bug
Subscription on DELETED event fires always despite of filters

To Reproduce
Steps to reproduce the behavior:
Run any subscription and will try to use filters for node field. After that delete something (that not in filter) and you will get notify despite of filters

Expected behavior

Filters is work

Screenshots
If i use playground on graphql-yoga api
image
Same on prisma api
image

Versions (please complete the following information):

  • Docker image prismagraphql/prisma:1.17

package.json of my graphql-yoga server


  "dependencies": {
    "apollo-errors": "^1.9.0",
    "bcryptjs": "^2.4.3",
    "graphql-cli": "^2.16.7",
    "graphql-middleware-forward-binding": "^1.3.2",
    "graphql-shield": "^3.2.4",
    "graphql-yoga": "^1.16.2",
    "jsonwebtoken": "^8.3.0",
    "nodemailer": "^4.6.7",
    "npm-run-all": "^4.1.3",
    "prisma": "^1.17.1",
    "prisma-binding": "^2.1.6"
  },

Subscription is just forwarding to prisma

const Subscription = {
  judge: {
    subscribe: async (parent, args, ctx, info) => {
      // console.log(parent, args, ctx, info)
      const judge = await ctx.db.subscription.judge(args, info)
      return judge
    }
  }
}

  • graphql-cli, prisma-binding, graphql-yoga, etc. if applicable

Additional context
P.S.
Also as you can see i have strange value in previousValue.id
CuidGCValue(cjmyxtna300pi0936kx8fimgz)
But i think for this i need to create another issue? Or is this expected format of id?

@MaksimKlepikov
Copy link
Author

Just trying it on Docker image prismagraphql/prisma:1.17.2
Same behavior

@marktani
Copy link
Contributor

This is a duplicate of #2847, which seems to be a regression.

@Sampite
Copy link

Sampite commented Aug 16, 2019

I think this issue wasn't related to #2847 sure, the id was wrong but there seems to be a problem with the filtering on the node of the subscription when deleting. Now the id is returned correctly but the something is not right with the where filters on the node.

I have a subscription with filtering on the node and
mutation_in: ['CREATED', 'DELETED']

When I subscribe with different parameters, on create only the correct filtered subscriptions get notified, and I get the data on the client no problem. But when a record is deleted all of the subscriptions get notified regardless of the filter set on the node parameter. I tested it several times, for example when I called the subscription 6 times with different filters, on create only 1 with the right filters set got notified, but when deleted the same node all of the 6 subscriptions got notified and received data on the client, sure on the other 5, the id didn't match anything in the cache of the related query, so nothing got removed, but code needlessly run 5 other times. It would be nice to know what causes this, and fix it, so there will be no useless network calls.

my subscription code:

logs: {
    subscribe: async (
      _parent,
      { queryDate, loggedBy, loggedOn, type },
      ctx,
    ) => {
      let whereInput: LogWhereInput = BuildLogWhereInput(
        queryDate,
        loggedBy,
        loggedOn,
        type,
      );     
      return ctx.db.$subscribe.log({
        mutation_in: ['CREATED', 'DELETED'],
        node: whereInput,
      });
    },
    resolve: ({
      mutation,
      node,
      previousValues,
    }: {
      mutation: MutationType;
      node: Log;
      previousValues: Log;
    }) => {      
      return {
        mutation,
        node: mutation === 'DELETED' ? previousValues : node,
      };
    },
  },
export function BuildLogWhereInput(
  queryDate: QueryDateData,
  loggedBy: string,
  loggedOn: string,
  type: LogType,
): LogWhereInput {
  let whereInput: LogWhereInput = {};

  // Set query dates, if type = ALL, we query all, so nothing set
  if (queryDate.type === QueryDateDataType.FROM) {
    whereInput.createdAt_gte = queryDate.from;
  } else if (queryDate.type === QueryDateDataType.SPAN) {
    whereInput.createdAt_gte = queryDate.from;
    whereInput.createdAt_lte = queryDate.to;
  }
  // Set additional query fields if we have them
  if (loggedBy) {
    whereInput.loggedBy = {
      id: loggedBy,
    };
  }
  if (loggedOn && type) {
    if (type === LogType.USER) {
      whereInput.onUserID = {
        id: loggedOn,
      };
    } else if (type === LogType.API) {
      whereInput.onApiID = {
        id: loggedOn,
      };
    }
  }
  if (type) {
    whereInput.type = type;
  }
  return whereInput;
}

the queryDate is called with type ALL so dates don't matter on subscriptions as we only want the newest ones anyway

versions:
OS: Ubuntu 18.04.3 LTS
typescript: 3.5.3
prisma: 1.34.5
prisma-client-lib: 1.34.5
and prisma is running a docker container: image: prismagraphql/prisma:1.34.5

Is the problem on my end, or maybe in Prisma code?
if more data is needed ask and I'll provide it.

@marktani can you reopen this issue for discussion please?

@AlejandroRodarte
Copy link

Writing a comment just to inform I am experiencing the same problem as @Sampite.

CREATED/UPDATED notifications are filtered properly, but DELETE subscriptions seem to not properly apply such filters.

@Sampite
Copy link

Sampite commented Sep 5, 2019

Hey @AlejandroRodarte,
Since than I solved it with a workaround, I don't use Prisma's subscriptions, instead I redesigned my server code, so I use graphql-subscriptions and publish changes with it inside all mutations, I want my subscriptions to know about. It's a little bit more code to write, but at least I'm in control of what and when gets published.

Still, there seems to be something wrong with Prismas delete subs. And as I did not get any response regarding the issue in this thread, maybe if you have the time and interested in solving it, create a new issue on this and reference this thread maybe.

Anyway Prisma2 will be production ready "soon" so maybe it doesn't worth the effort.

@niceropez
Copy link

niceropez commented Nov 18, 2019

@Sampite & @AlejandroRodarte
Hey Guys!

Something very similar to you happens to me. On my server (localhost: 8000) subscriptions have strange behavior. When I try to filter with "{where: {node: {...}}}" nothing works, just the subscription stays "Listening ...". And when I remove the filters "node" works! This means that "mutations_in [...]" works!

On the other hand, subscriptions with filters "node" on the Prisma server (localhost: 4466 --on docker--) works!

It's my second day diving all over the Prisma forum and other pages, and I can't find any solution. I think I will follow the @Sampite solution. Although I think I will create a thread after hearing your suggestions.

Here a bit of my code:

//SCHEMAS:
type Subscription {
newPet(where: PetSubscriptionWhereInput): PetSubscriptionPayload
}

//RESOLVERS:
async function newPetSubscribe(parent, args, context, info) {
return await context.prisma.$subscribe.pet(args)
}
const newPet = {
subscribe: newPetSubscribe,
resolve: payload => {
return payload
},
}

@Sampite
Copy link

Sampite commented Nov 19, 2019

@BiosTEC
Hey mate! I don't know if you solved it yet but looks like your subscription definiton is
newPet(where: PetSubscriptionWhereInput): PetSubscriptionPayload this means in the
async function newPetSubscribe(parent, args, context, info) { ... function the args object contains one filed labeled where type PetSubscriptionWhereInput and than you pass it to the return await context.prisma.$subscribe.pet(args) here but the $subscribe.pet() function does not take a where filed, it takes the filters, or on object example: { mutation_in: ['CREATED', ...], node: { ... } }
as show here maybe thats the source of your problem, if you are using Typescript you should check if every type is right, if you are using JS check what you get in the args, and what you need to input in the prisma sub handler and try to match it.

On an other note, as prisma is in a weird place because prisma2 is not production ready yet, and I needed some solutions that prisma1 cant handle, and I'm working with a full Typescript project. I'm in the process of rewriting my server code and moving to TypeGraphQL + TypeORM so i don't have to define the schema 2times and other handy stuff with decorators. Maybe if you cant solve all your problems and can't wait till prisma2 its worth to check out this stack, and I'm still using Apollo server/client for graphql

@niceropez
Copy link

niceropez commented Nov 20, 2019

Wow!
You saved me @Sampite , I had a couple of days on it and I was already implementing my Mutations + Subscriptions with pubSub from graphql-subscriptions. I had read the documentation of version 1.34, but I had overlooked that there was no longer a "where" filter in the subscriptions.

When I was reading about how it works under the hood how subscriptions work, I saw that there were different libraries with anchors to servers such as redis, RabbitMQ, Google PubSub etc., which give the pubSub system greater stability. I think Prisma works with RabbitMQ, am I correct?

I will ask you a couple of questions since I am a new one within the framework of Prisma,

Thanks for everything!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants