@eigenjoy/graffiti-mongoose

    4.3.3 • Public • Published

    graffiti-mongoose npm version

    Codeship Status for RisingStack/graffiti-mongoose

    Mongoose (MongoDB) adapter for the graffiti GraphQL ORM.

    graffiti-mongoose generates GraphQL types and schemas from your existing mongoose models, that's how simple it is. The generated schema is compatible with Relay.

    For quick jump check out the Usage section.

    Install

    npm install graphql @risingstack/graffiti-mongoose --save

    Example

    Check out the /example folder.

    cd graffiti-mongoose
    npm install # install dependencies in the main folder 
    cd example
    npm install # install dependencies in the example folder 
    npm start # run the example application and open your browser: http://localhost:8080 

    Usage

    This adapter is written in ES6 and ES7 with Babel but it's published as transpiled ES5 JavaScript code to npm, which means you don't need ES7 support in your application to run it.

    Example queries can be found in the example folder.

    usual mongoose model(s)
    import mongoose from 'mongoose';
     
    const UserSchema = new mongoose.Schema({
      name: {
        type: String,
        // field description
        description: 'the full name of the user'
      },
      hiddenField: {
        type: Date,
        default: Date.now,
        // the field is hidden, not available in GraphQL
        hidden: true
      },
      age: {
        type: Number,
        indexed: true
      },
      friends: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
      }]
    });
     
    const User = mongoose.model('User', UserSchema);
    export default User;
    graffiti-mongoose
    import {getSchema} from '@risingstack/graffiti-mongoose';
    import graphql from 'graphql';
    import User from './User';
     
    const options = {
      mutation: false // mutation fields can be disabled
    };
    const schema = getSchema([User], options);
     
    const query = `{
        users(age: 28) {
          name
          friends(first: 2) {
            edges {
              cursor
              node {
                name
                age
              }
            }
            pageInfo {
              startCursor
              endCursor
              hasPreviousPage
              hasNextPage
            }
          }
        }
      }`;
     
    graphql(schema, query)
      .then((result) => {
        console.log(result);
      });

    Supported mongoose types

    • Number
    • String
    • Boolean
    • Date
    • [Number]
    • [String]
    • [Boolean]
    • [Date]
    • ObjectId with ref (reference to other document, populate)
    • more types coming soon...

    Supported query types

    • query
      • singular: for example user
      • plural: for example users
      • node: takes a single argument, a unique !ID, and returns a Node
      • viewer: singular and plural queries as fields

    Supported query arguments

    • indexed fields
    • "id" on singular type
    • array of "id"s on plural type

    Which means, you are able to filter like below, if the age is indexed in your mongoose model:

    users(age: 19) {}
    user(id: "mongoId1") {}
    user(id: "relayId") {}
    users(id: ["mongoId", "mongoId2"]) {}
    users(id: ["relayId1", "relayId2"]) {}
    

    Supported mutation types

    • mutation
      • addX: for example addUser
      • updateX: for example updateUser
      • deleteX: for example deleteUser

    Supported mutation arguments

    • scalar types
    • arrays
    • references

    Examples:

    mutation addX {
      addUser(input: {name: "X", age: 11, clientMutationId: "1"}) {
        id
        name
      }
    }
    
    mutation updateX {
      updateUser(input: {id: "xpmsdfonasd", age: 10, clientMutationId: "2"}) {
        id
        name
        age
      }
    }
    
    mutation deleteX {
      deleteUser(input: {id: "xpmsdfonasd", clientMutationId: "3"}) {
        ok
      }
    }
    

    Resolve hooks

    You can specify pre- and post-resolve hooks on fields in order to manipulate arguments and data passed in to the database resolve function, and returned by the GraphQL resolve function.

    You can add hooks to type fields and query fields (singular & plural queries, mutations) too. By passing arguments to the next function, you can modify the parameters of the next hook or the return value of the resolve function.

    Examples:

    • Query, mutation hooks (viewer, singular, plural, mutation)
    const hooks = {
      viewer: {
        pre: (next, root, args, {rootValue}) => {
          const {request} = rootValue;
          // authorize the logged in user based on the request
          authorize(request);
          next();
        },
        post: (next, value) => {
          console.log(value);
          next();
        }
      },
      // singular: {
      //   pre: (next, root, args, context) => next(),
      //   post: (next, value, args, context) => next()
      // },
      // plural: {
      //   pre: (next, root, args, context) => next(),
      //   post: (next, value, args, context) => next()
      // },
      // mutation: {
      //   pre: (next, args, context) => next(),
      //   post: (next, value, args, context) => next()
      // }
    };
    const schema = getSchema([User], {hooks});
    • Field hooks
    const UserSchema = new mongoose.Schema({
      name: {
        type: String,
        hooks: {
          pre: (next, root, args, {rootValue}) => {
            const {request} = rootValue;
     
            // authorize the logged in user based on the request
            // throws error if the user has no right to request the user names
            authorize(request);
            next();
          },
          // manipulate response
          post: [
            (next, name) => next(`${name} first hook`),
            (next, name) => next(`${name} & second hook`)
          ]
        }
      }
    });
    query UsersQuery {
      viewer {
        users(first: 1) {
          edges {
            node {
              name
            }
          }
        }
      }
    }
    
    {
      "data": {
        "viewer": {
          "users": {
            "edges": [
              {
                "node": {
                  "name": "User0 first hook & second hook"
                }
              }
            ]
          }
        }
      }
    }

    Test

    npm test

    License

    MIT

    Install

    npm i @eigenjoy/graffiti-mongoose

    DownloadsWeekly Downloads

    6

    Version

    4.3.3

    License

    MIT

    Last publish

    Collaborators

    • eigenjoy