# Add mandatory server side filtering on the query resolver

**URL:** https://community.neo4j.com/t/add-mandatory-server-side-filtering-on-the-query-resolver/37674
**Category:** GraphQL & GRANDstack
**Tags:** javascript, graphql
**Created:** [May 1, 2021, 6:13am UTC](https://community.neo4j.com/t/add-mandatory-server-side-filtering-on-the-query-resolver/37674 "2021-05-01T06:13:33Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![pwmb](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/pwmb/32/18050_2.png) [@pwmb](https://community.neo4j.com/u/pwmb)
#### Post date: [May 1, 2021, 6:13am UTC](https://community.neo4j.com/t/add-mandatory-server-side-filtering-on-the-query-resolver/37674/1 "2021-05-01T06:13:33Z")

</div>

So I want to write a custom query resolver where user are querying for `Projects`

GQL type looks something like this

```gql
type Projects {
  id: ID!
  name: String!
  users: [User!]! @relation(name: "CAN_ACCESS", direction: IN)
  # ... etc
}

```

Now user can query this as usual from the exposed graphql endpoint.

But now we want to add this logic that only authorised users (present in `users: [User!]!`) can only see the results, mind you this is a server side enforced filter and not client side.

> Say there are 5 projects in total but **Tom** has access to only 2 out of those 5 projects he should be able to view only those 2 projects.

How to achieve this ? I wrote a custom Query resolver (with cypher) but still dont see the desired results as I am not sure how to pass filter to `neo4jgraphql(...)`

Code I have now:

```ts
export const QueryProjects = async (root, args, ctx, info) => {
  const results = await ctx.session.readTransaction((t) =>
    t.run(
      `MATCH (:User {id: $id}) -[:CAN_ACCESS]-> (p:Project)
      RETURN p`,
      { id: ctx.user.id }
    )
  )
  return await neo4jgraphql(root, args, ctx, info);

```

how do I take the filtered results and pass it to `neo4jgraphql` so that it then return a valid grapgql response?

---

<div class="post-metadata">

### Author: ![lyonwj](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/lyonwj/32/27358_2.png) [@lyonwj](https://community.neo4j.com/u/lyonwj)
#### Post date: [May 3, 2021, 6:11pm UTC](https://community.neo4j.com/t/add-mandatory-server-side-filtering-on-the-query-resolver/37674/2 "2021-05-03T18:11:06Z")

</div>

I think you can accomplish this with a `@cypher` directive making use of `cypherParams` in the context object to inject the user id value from the context into the Cypher query. Any values in the `cypherParams` object in the context will be passed as parameters to the Cypher query.

So, first grab the user object (I'm assuming you're using some auth middleware that adds the user to the req object) and inject it into context.cypherParams:

```auto
server = new ApolloServer({
  schema,
  context: ({ req }) => {
    return {driver, cypherParams: { user: req.user}}
  }

```

Then in the GraphQL schema you can add a `@cypher` schema directive with your authorization logic that references `cypherParams.user.id`:

```auto
type Query {
  myProjects: [Project] @cypher(statement: "MATCH (u:User {id: $cypherParams.user.id})-[:CAN_ACCESS]->(p:Project) RETURN p"
}

```

We did something similar in the GRANDcast.fm podcast demo application here: [grandcast.fm/schema.graphql at master · johnymontana/grandcast.fm · GitHub](https://github.com/johnymontana/grandcast.fm/blob/master/api/src/schema.graphql#L38-L44)

Note that this is using the old `neo4j-graphql-js` library, you might be interested in the newer [official @neo4j/graphql library](https://neo4j.com/docs/graphql-manual/current/getting-started/) which has a [more powerful authorization model](https://neo4j.com/docs/graphql-manual/current/auth/). For this use case there is an `@auth` directive that supports [adding a `where` rule](https://neo4j.com/docs/graphql-manual/current/auth/authorization/where/) that can automatically add the authorization rule filter to the generated Cypher query so not even the `@cypher` schema directive is needed.
