prisma-relay-cursor-connection
Prisma's findMany
method to support Relay Cursor Connections
Extend
Installation • Usage • Contributing • Contributors • License
Installation
yarn add @devoxa/prisma-relay-cursor-connection
This module has a peer dependency on @prisma/client
version ^2.0.0 || ^3.0.0
.
Usage
General Usage
This module validates the connection arguments to make sure they work with Prisma. The following combinations are supported:
{}
All resources{ first: number }
The first X resources{ first: number, after: string }
The first X resources after the id Y{ last: number }
The last X resources{ last: number, before: string }
The last X resources before the id Y
Two cases need to be checked in your code if you are passing in user-provided data to prevent the user from reading out too many resources at once:
- One of
first
|last
has to be defined first
|last
have to be below a reasonable maximum (e.g. 100)
import {
findManyCursorConnection,
ConnectionArguments,
} from '@devoxa/prisma-relay-cursor-connection'
const result = await findManyCursorConnection(
(args) => client.todo.findMany(args),
() => client.todo.count(),
{ first: 5, after: '5c11e0fa-fd6b-44ee-9016-0809ee2f2b9a' } // typeof ConnectionArguments
)
Type-Safe Arguments
You can also use additional FindManyArgs
while keeping type safety intact:
import { findManyCursorConnection } from '@devoxa/prisma-relay-cursor-connection'
const baseArgs = {
select: { id: true, isCompleted: true },
where: { isCompleted: true },
}
const result = await findManyCursorConnection(
(args) => client.todo.findMany({ ...args, ...baseArgs }),
() => client.todo.count({ where: baseArgs.where }),
{ last: 5, before: '5c11e0fa-fd6b-44ee-9016-0809ee2f2b9a' }
)
// Type error: Property text does not exist
result.edges[0].node.text
Custom Cursors
By default, the cursor is the id
field of your model. If you would like to use a different field,
a compound index, or handle encoding/decoding, you can pass the following options:
import { findManyCursorConnection } from '@devoxa/prisma-relay-cursor-connection'
const result = await findManyCursorConnection(
(args) => client.todo.findMany(args),
() => client.todo.count(),
{ first: 5, after: 'eyJpZCI6MTZ9' },
{
getCursor: (record) => ({ id: record.id }),
encodeCursor: (cursor) => Buffer.from(JSON.stringify(cursor)).toString('base64'),
decodeCursor: (cursor) => JSON.parse(Buffer.from(cursor, 'base64').toString('ascii')),
}
)
You can find more examples for custom cursors in the unit tests.
Custom Edges & Nodes
By default, the edge consists of the cursor
and the node
. If you would like to add additional
fields to the edge or the node, you can pass the following option:
import { findManyCursorConnection } from '@devoxa/prisma-relay-cursor-connection'
const result = await findManyCursorConnection<
Todo,
{ id: string },
Todo & { extraNodeField: string },
{ extraEdgeField: string; cursor: string; node: Todo & { extraNodeField: string } }
>(
(args) => client.todo.findMany(args),
() => client.todo.count(),
{ first: 5, after: 'eyJpZCI6MTZ9' },
{
recordToEdge: (record) => ({
node: { ...record, extraNodeField: 'Foo' },
extraEdgeField: 'Bar',
}),
}
)
Contributing
# Setup the test database
yarn prisma migrate dev --preview-feature
# Run the tests
yarn test
Contributors
Thanks goes to these wonderful people (emoji key):
David Reeß 💻 📖 |
Sean Matheson 💻 |
Marc 💻 |
Jeong Seong Dae 💻 |
Ahmet Uysal 💻 |
Nick Randall 💻 |
Igor Urminček 📖 |
This project follows the all-contributors specification. Contributions of any kind welcome!
License
MIT