UNPKG

mongo-relay-connection

Version:

Helper for building relay connection from mongoose. Support dynamic collection, but only for single (unique or non-unique) field sorting.

151 lines (127 loc) 5.15 kB
[![build status][travis-image]][travis-url] [![NPM version][npm-image]][npm-url] [![Coverage Status][coverall-image]][coverall-url] [![js-standard-style][standard-image]][standard-url] [![devDependency Status][david-image]][david-url] [![devDevDependency Status][david-image-dev]][david-url-dev] [travis-image]: https://travis-ci.org/jackytck/mongo-relay-connection.svg?branch=master [travis-url]: https://travis-ci.org/jackytck/mongo-relay-connection [npm-image]: https://img.shields.io/npm/v/mongo-relay-connection.svg [npm-url]: https://npmjs.org/package/mongo-relay-connection [coverall-image]: https://coveralls.io/repos/jackytck/mongo-relay-connection/badge.svg?branch=master [coverall-url]: https://coveralls.io/github/jackytck/mongo-relay-connection?branch=master [standard-image]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg [standard-url]: http://standardjs.com [david-image]: https://david-dm.org/jackytck/mongo-relay-connection.svg [david-url]: https://david-dm.org/jackytck/mongo-relay-connection [david-image-dev]: https://david-dm.org/jackytck/mongo-relay-connection/dev-status.svg [david-url-dev]: https://david-dm.org/jackytck/mongo-relay-connection#info=devDependencies ### Install ```bash yarn add mongo-relay-connection graphql graphql-relay ``` `graphql` and `graphql-relay` are required as peer dependencies. ### Overview To assist building a **Relay Connection** type from a mongoose schema. It supports **dynamic collection**. The order could be based on a field that is **not necessarily unique**. And existing schema **need not be changed** at all. It is based on the Relay [pagination algorithm](https://facebook.github.io/relay/graphql/connections.htm#sec-Pagination-algorithm). But as including a value for both first and last is confusing, the last is ignored if both are given. | # | after | first | before | last | remarks | support | |:--: |:-----: |:-----: |:------: |:----: |:-----------: |:-------: | | 1 | | | | | returns all | ✓ | | 2 | | | | ✓ | | ✓ | | 3 | | | ✓ | | | ✓ | | 4 | | | ✓ | ✓ | | ✓ | | 5 | | ✓ | | | | ✓ | | 6 | | ✓ | | ✓ | same as #5 | ✗ | | 7 | | ✓ | ✓ | | | ✓ | | 8 | | ✓ | ✓ | ✓ | same as #7 | ✗ | | 9 | ✓ | | | | | ✓ | | 10 | ✓ | | | ✓ | | ✓ | | 11 | ✓ | | ✓ | | | ✓ | | 12 | ✓ | | ✓ | ✓ | | ✓ | | 13 | ✓ | ✓ | | | | ✓ | | 14 | ✓ | ✓ | | ✓ | same as #13 | ✗ | | 15 | ✓ | ✓ | ✓ | | | ✓ | | 16 | ✓ | ✓ | ✓ | ✓ | same as #15 | ✗ | ### Usage Suppose you want to do cursor based pagination over a collection: ``` js // models/product.js import mongoose, { Schema } from 'mongoose' const ProductSchema = new Schema({ name: String, type: String, price: Number }) export default mongoose.model('Product', ProductSchema) ``` First create a corresponding GraphQLObjectType: ``` js // types/product.js import { GraphQLObjectType, GraphQLID, GraphQLString, GraphQLInt } from 'graphql' const Product = new GraphQLObjectType({ name: 'Product', fields: { id: { type: GraphQLID }, name: { type: GraphQLString }, type: { type: GraphQLString }, price: { type: GraphQLInt } } }) export default Product ``` Then create your query by defining the type, args, and resolve function. Here all the food product is selected and sorted by price descendingly: ``` js import { GraphQLObjectType } from 'graphql' import { mrType, mrArgs, mrResolve } from 'mongo-relay-connection' import Product from './types/product' import ProductModel from './models/product' const foodTypes = [ "Bacon", "Cheese", "Chicken", "Chips", "Fish", "Pizza", "Salad", "Sausages", "Tuna" ] const RootQuery = new GraphQLObjectType({ name: 'RootQuery', fields: { allFoodProducts: { type: mrType('FoodProduct', Product), args: mrArgs, resolve (parentValue, args) { const query = { type: { $in: foodTypes } } const opts = { cursorField: 'price', direction: -1 } return mrResolve(args, ProductModel, query, opts) } } } }) export default RootQuery ``` Boom, you're done! No third step. All the hard work of resolving is done for you. ### Limitation It is based on sorting on a single given field (default is _id). If the field is not unique, it is compounded with _id as the secondary sort. So it could only be sorted in one given dimension. ### License MIT