0.1.0 • Published 7 years ago

graphql-orm-mongoose v0.1.0

Weekly downloads
3
License
-
Repository
-
Last release
7 years ago

Mongoose adapter for the GraphQL ORM.

graphql-mongoose 提供一个全新的方式来定义数据模型和方法, 自动生成 GraphQL Schema 和 mongoose Schema

安装

npm install git+ssh://git@120.25.198.74:root/graphql-mongoose.git --save

例子

Check out : todomvc-graphql-mongoose

cd todomvc-graphql-mongoose
npm install # install dependencies in the example folder
npm start # run the example application and open your browser: http://localhost:9413

用法

定义数据模型

User.js

import co from 'co'
import Schema from 'graphql-mongoose'

let UserSchema = Schema.model('User').doc("用户").fields(
  {
    username: {
      $type: String,
      index: true,
      required: true
    },
    age: Number
  }
)
生成 Graphql Schema
import mongoose from 'mongoose'

//连接 MongoDb
const mongoUrl = process.env.MONGO_URI || 'mongodb://localhost:27017/test'
console.log("Using mongodb " + mongoUrl)

mongoose.connect(mongoUrl)

import Schema from 'graphql-mongoose'

import UserSchema from './User'


let graphqlSchema = Schema.build({
  models: [UserSchema]
})

定义模型的属性

类型 = 基本类型 | 数组类型 | 组合类型 | Type类型 | 引用类型
基本类型 = Number | String | Boolean | Date | JSON
数组类型 = [类型]
组合类型 = { 模型属性1, 模型属性2, ...}

模型属性 = key: 类型 | {    
                       $type: 类型, 
                       index: true|false,                      // 是否需要MongoDb index
                       unique: true |false,                    // 标记属性是否唯一
                       required:true|false,                    // 是否必填的属性
                       doc: String,                            // key的说明
                       
                       get: function(value) => any,            // 属性的Get方法, 用于必要时的转化
                       set: function(value) => any,            // 属性的Set方法, 用于设置属性值时的转化
                       
                       match:regexp | [regexp, errorMsg],      // 当$type为String时, 做Regexp 验证
                       maxlength: value | [value, errorMsg],   // 当$type为String时, 做字符串最大长度验证
                       minlength: value | [value, errorMsg],   // 当$type为String时, 做字符串最小长度验证
                       lowercase: true,                        // 当$type为String时, 保存值时自动转小写
                       uppercase: true,                        // 当$type为String时, 保存值时自动转大写
                       trim: true,                             // 当$type为String时, 保存值时自动trim
                       max: value | [value, errorMsg],         // 当$type为Number或Date时, 做最大验证
                       min: value | [value, errorMsg],         // 当$type为Number或Date时, 做最小验证
                       expires: Number | String,               // 当$type为Date时, 通过设置expires, 
                                                               // MongoDb会自动把expire document 删除.
                                                               // 可能的值: 60*60*24 ,  '24h', '2d'
                       validate:{                              // 自定义Validator
                                 validator: (value) =>boolean,
                                 message: String
                                },
                                
                       hidden: true|false,                     // hidden为true, 对应的field将不会出现在graphql schema中
                       searchable: true|false,                 // 是否可以在plural的Query中出现
                       initializable:true|false,               // 是否可以在add的Mutation中出现
                       mutable:true|false,                      // 是否可以在update的Mutation中出现
                       enumValues: {enum1:value1, enum2:value2, ...},  // 定义enum值
                       args: 类型,                                      // 配合resolve使用,定义的参数类型
                       resolve: (source, args, info, models, invoker) => any    // 如果定义了resolve方法, 则该类型对应的属性
                                                                       // 值是通过resolve方法获得,不在映射到MongoDb
                      }

Type类型用于定义公共的Structure, 便于在不同的Model中共享

import Schema from 'graphql-mongoose'

let Location = Schema.type('Location',  {
    doc: "经纬度",
    fields: {
      lat: Number,
      lng: Number
    }
  }
)

// 定义继承Node接口的非 Model type
let Me = Schema.type('Me',  {
             doc: "当前用户信息",
             fields: {
               loginUser:Schema.modelRef('User')
             },
             resolve: (id, info, models, invoker) => {
                //get the loginUser and return the Me data
                
                return {
                  loginUser:...
                }
             }
           }
         )

引用类型是为了解决Model类型间的引来,

用法:

import Schema from 'graphql-mongoose'

const UserType = Schema.modelRef('User') // 应用User Model

let TodoSchema = Schema.model("Todo").fields(
  {
    title: {
      $type: String,
      index: true,
      required: true
    },
    description: String,
    completed: {
      $type: Boolean,
      required: true
    },
    user: UserType,
    dueAt: Date
  }
)

定义模型的Query方法

import Schema from 'graphql-mongoose'

let UserSchema = Schema.model('User').fields(
  ......
).queries({
    ${方法名}:{ 
               $type: 类型, 
               doc: String,                      // Query的说明文档
               args: 类型,                               // 定义的参数类型
               resolve: (args, info, models, invoker) => any     // 逻辑
              }
  }
)

定义模型的Mutation方法

import Schema from 'graphql-mongoose'

let UserSchema = Schema.model('User').fields(
  ......
).mutations({
   方法名:{ 
             doc: String,                                          // Mutation的说明文档
             inputFields: {field1:组合类型, field2:组合类型, ...}, 
             outputFields: {模型属性1, 模型属性2, ...},                      // 定义的参数类型
             mutateAndGetPayload: (args, info, models, invoker) => any     // 逻辑
          }
  }
)

定义模型的实例方法

import Schema from 'graphql-mongoose'

let UserSchema = Schema.model('User').fields(
  ......
).methods({
    方法名:Function
  }
)

定义模型的静态方法

import Schema from 'graphql-mongoose'

let UserSchema = Schema.model('User').fields(
  ......
).statics({
    方法名:Function
  }
)

生成relay的connection风格接口

import co from 'co'
import Schema from 'graphql-mongoose'

const TodoType = Schema.modelRef('Todo')
const UserType = Schema.modelRef('User')

export default Schema.model('User').fields(
  {
    username: {
      $type: String,
      index: true,
      required: true
    },
    age: Number

  }).links(
  {
    todos: {
      $type: Schema.Connection.type(TodoType),
      args:Schema.Connection.args,
      resolve: (user, args, info, {Todo}) => co(function *() {
        return yield Schema.Connection.fromModel(Todo,{
          ...args,
          user: user._id
        },info)
      })
    }
  }
)

在resolve方法内调用Query / Mutation

通过在resolve方法中的invoker参数,可以在继承当前request的环境中,执行对应的query/mutation

    mutateAndGetPayload: ({userId}, info, {User}, invoker) => co(function *() {
        ...
        const data = yield invoker("query() {users(first:3) {edges {node{id username}}}}")
        ...
    })

可选择Option

    softDelete: 是否支持软删除,即只通过deleted field 来标记删除, 默认false
    timestamps: 是否自动生产 createdAt 和 updatedAt , 默认 true
    methods: {
      singularQuery: 是否生产单个查询方法,默认true,
      pluralQuery: 是否生产集合查询方法,默认true,
      add: 是否生产add方法,默认true,
      update: 是否生产update方法,默认true,
      remove: 是否生产remove方法,默认false,
      delete: 是否生产delete方法,默认true
    }
0.1.0

7 years ago