mercurius-js / cache

Adds an in-process caching layer to Mercurius. Federation is fully supported.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

adopt cache for loaders

simone-sanfratello opened this issue · comments

I'd like to use cache for loaders as well as for resolvers, for example

'use strict'

const Fastify = require('fastify')
const mercurius = require('mercurius')
const cache = require('mercurius-cache')

const app = Fastify()

const dogs = [{ name: 'Max' },
{ name: 'Charlie' },
{ name: 'Buddy' },
{ name: 'Max' }]

const owners = {
  Max: { name: 'Jennifer' },
  Charlie: { name: 'Sarah' },
  Buddy: { name: 'Tracy' }
}

const schema = `
  type Human {
    name: String!
  }

  type Dog {
    name: String!
    owner: Human
  }

  type Query {
    dogs: [Dog]
  }
`

const resolvers = {
  Query: {
    dogs(_, params, { reply }) {
      return dogs
    }
  }
}

const loaders = {
  Dog: {
    async owner(queries, { reply }) {
      return queries.map(({ obj }) => owners[obj.name])
    }
  }
}

app.register(mercurius, {
  schema,
  resolvers,
  loaders,
})

app.register(cache, {
  ttl: 9,
  onHit(type, fieldName) {
    console.log(`hit ${type} ${fieldName}`)
  },
  onMiss(type, fieldName) {
    console.log(`miss ${type} ${fieldName}`)
  },
  policy: {
    resolvers: {
      Query: {
        dogs: {
          ttl: 5,
          // ...
        }
      }
    },
    loaders: {
      Dog: {
        owner: {
          ttl: 10,
          // ...
        }
      }
    }
  }
})

app.listen(3000)

I think it would work out of the box, won't it?

at the moment it's not caching loaders, only resolvers in Query type, maybe it needs just to add it, I still don't know

I mean that this should work as is or within minimal changes. There is no difference between resolvers and loaders after theGrapHQL schema is assembled.

'use strict'

const Fastify = require('fastify')
const mercurius = require('mercurius')
const cache = require('mercurius-cache')

const app = Fastify()

const dogs = [{ name: 'Max' },
{ name: 'Charlie' },
{ name: 'Buddy' },
{ name: 'Max' }]

const owners = {
  Max: { name: 'Jennifer' },
  Charlie: { name: 'Sarah' },
  Buddy: { name: 'Tracy' }
}

const schema = `
  type Human {
    name: String!
  }

  type Dog {
    name: String!
    owner: Human
  }

  type Query {
    dogs: [Dog]
  }
`

const resolvers = {
  Query: {
    dogs(_, params, { reply }) {
      return dogs
    }
  }
}

const loaders = {
  Dog: {
    async owner(queries, { reply }) {
      return queries.map(({ obj }) => owners[obj.name])
    }
  }
}

app.register(mercurius, {
  schema,
  resolvers,
  loaders,
})

app.register(cache, {
  ttl: 9,
  onHit(type, fieldName) {
    console.log(`hit ${type} ${fieldName}`)
  },
  onMiss(type, fieldName) {
    console.log(`miss ${type} ${fieldName}`)
  },
  policy: {
    resolvers: {
      Query: {
        dogs: {
          ttl: 5,
          // ...
        }
      }
      Dog: {
        owner: {
          ttl: 10,
          // ...
        }
      }
    }
  }
})

app.listen(3000)

Looking at the code, this might not be working right now. Anyway, this is the same of #74.

👍 I'd go for the minimal required changes