Skip to content

jackytck/mongo-relay-connection

Repository files navigation

build status NPM version Coverage Status js-standard-style devDependency Status devDevDependency Status

Install

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. 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:

// 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:

// 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:

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

About

Assist building relay connection from mongoose.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •