在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称(OpenSource Name):sayden/graphql-mongodb-example开源软件地址(OpenSource Url):https://github.com/sayden/graphql-mongodb-example开源编程语言(OpenSource Language):JavaScript 100.0%开源软件介绍(OpenSource Introduction):graphql-mongodb-exampleThis is a project to show how to work with a Express app with GraphQL and MongoDB persistence... written in ES6 :) How to install the example$ git clone https://github.com/sayden/graphql-mongodb-example.git
$ npm install
$ npm run populate
$ npm start Using itThis GraphQL example doesn't have any UI. For a UI example check my Relay example in this relay example For easyness, we will use Postman to make queries. For a GraphQL query you must use
query RootQuery {
user (id:0) {
name
surname
}
} Gives {
"data": {
"user": {
"name": "Richard",
"surname": "Stallman"
}
}
}
query RootQuery {
user (id:2) {
name
surname
age
_id
}
} Gives {
"data": {
"user": {
"name": "Linux",
"surname": "Torvalds",
"age": 8,
"_id": "55ddeec2a54c37e61e0a2120"
}
}
}
mutation RootMutation {
addUser (name: "Bjarne", surname:"Stroustrup", age:64) {
name
surname
_id
age
}
} Gives {
"data": {
"addUser": {
"name": "Bjarne",
"surname": "Stroustrup",
"_id": "55ddf61ed082460325e2b65c",
"age": 64
}
}
} Checking MongoDB: {
"name" : "Bjarne",
"surname" : "Stroustrup",
"age" : 64,
"_id" : ObjectId("55ddf61ed082460325e2b65c"),
"id" : "55ddf61ed082460325e2b65b",
"__v" : 0
} GraphQLGraphQL is a new concept to define queries around a front end. It's a mix between SQL and REST but the best way to understand it is through a example. The example applicationThe application is pretty simple, uses an app.js where Express is getting configured and where it imports the Schema of the app. Our only endpoint will be '/'. Soon you will see that we don't need more. We also have a 'schema.es6' that hold most of the GraphQL schema configuration. But first lets start with the models Models folderIn the models folder is where most of the magic is happening. When you open it, you will see a subfolder called User.
So, in any normal development we could have a Mongoose schema that we use to connect to our MongoDB instance. Nothing has change yet. The concept of Query and MutationIn GraphQL we are going to separate the actions of our API between Queries (they don't alter the DDBB so they can be processed in parallel, typical GET in REST or SELECT * FROM... in SQL) and Mutations (they alter the database and they are processed serially, a POST, DELETE, PUT in REST or a DELETE FROM, INSERT INTO... in SQL) 4 files for every GraphQL "model"This is a personal preference, to split the Model in 4 files as the could grow dangerously and I don't like big (>1000 lines) files.
User type fileThe User type file is where we really define the properties of an model. We define what it is compose of but we aren't defining yet what it can do. So, for example, a typical User Type file could be like the following: exports default new GrapqhQLObjectType({
name: 'User',
description: 'A user type in our application',
fields: () => {
_id:{
type: new GraphQLNonNull(GraphQLID)
},
name:{
type: new GraphQLNonNull(GraphQLString)
},
surname:{
type: new GraphQLNonNull(GraphQLString)
},
age: {
type: GraphQLInt
}
}
});
Really really simple, isn't it? User Queries fileIn the User Queries, we will define the type of operations that can ask for information to our persistence layer (our database) but cannot modify the database. export default {
user: {
type: UserType,
args: {
id: {
type: GraphQLID
}
},
resolve: (root, {id}) => {
return new Promise((resolve, reject) => {
//User is a Mongoose schema
User.find({}, (err, res) => {
// Actually, we are not searching the ID but returning the position in the iterator
err ? reject(err) : resolve(res[id]);
});
});
}
}
};
User Mutations fileOur mutations file will contain operations to execute serially that can alter our database. It's very similar to the queries file: export default {
addUser:{
type:UserType,
args: {
name:{
name:'name',
type:new GraphQLNonNull(GraphQLString)
},
surname:{
name:'surname',
type: new GraphQLNonNull(GraphQLString)
},
age: {
name:'age',
type: GraphQLInt
}
},
resolve: (root, {name, surname}) => {
//Creates a new Mongoose User object to save
var newUser = new User({name:name, surname:surname});
return new Promise((resolve, reject) => {
newUser.save((err, res) => {
err ? reject(err): resolve(res);
});
});
}
}
};
User QL fileFinally when defining models, we like to use a import _UserType from './HobbyTypeQL.es6';
import _UserQueries from './UserQueriesQL.es6';
import _UserMutations from './UserMutationsQL.es6';
export const UserType = _UserType;
export const UserQueries = _UserQueries;
export const UserMutations = _UserMutations; This is not mandatory at all, but structurally I liked more the approach of importing a unique object for every model in the next file, the schema. The schema fileSchema is a bit more complex. We will join here all the models operations. let RootQuery = new GraphQLObjectType({
name: 'Query', //Return this type of object
fields: () => ({
user: UserQueries.user,
userList: UserQueries.userList
})
});
let RootMutation = new GraphQLObjectType({
name: "Mutation",
fields: () => ({
addUser: UserMutations.addUser
})
});
let schema = new GraphQLSchema({
query: RootQuery,
mutation: RootMutation
});
export default schema;
We have our schema complete. Now we only have to expose it through an endpoint. The ServerThe server is a common Mongoose+Express server with a small modification: app.use(bodyparser.text({type: 'application/graphql'}));
app.post('/', (req, res) => {
//Execute the query
graphql(schema, req.body)
.then((result) => {
res.send(result);
});
});
RelayYou can see a more complex example of this using Relay here: https://github.com/sayden/relay-starter-kit ContributionsPlease feel free to help, specially with grammar mistakes as english is not my mother language and I learned it watching "Two and a half men" :) Any other contribution must be on the road of simplicity to understand and to help others to learn GraphQL. Contributions must have a README file associated or to update this. |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论