美文网首页
Visual Studio Code开发基于Nodejs的RES

Visual Studio Code开发基于Nodejs的RES

作者: 大仙出游 | 来源:发表于2019-04-17 15:13 被阅读0次

    优势:按需请求,不多不少!

    一、环境配置

    1.安装Visual Studio Code的最新版本

    2.安装MongoDB的最新Windows或Linux版本承载数据,把数据导入graphql数据库中,集合名称为:base.diseases,是国家标准疾病库字典,本文演示数据只有很少的三个键值对:code,name,assistant,如果你有1024个,则慢慢加吧!不过我有个工具可以批量秒生成!

    3.安装NodeJS的最新版本用于承载项目。

    4.升级npm到最新版本,执行:npm i -g npm

    5.找个美好的地方创建graphql-demo目录,环境配置完毕。

    二、初始化项目

    1.打开Visual Studio Code开发工具,并立即打开刚刚创建好的graphql-demo目录。

    2.在菜单“查看”中单击“终端”,或者按Ctrl+`,就是波浪线键上靠下边的那个反引号,打开终端,执行:npm init -y,会出现package.js文件,说明创建成功,注意观察一下此文件的内容,具体内容请查阅网络资料吧,这里不再阐述。

    3.安装应用程序相关的必须依赖包(注意用空隔隔开):npm i nodemon mongoose express express-graphql graphql body-parser,安装完毕后,在package.js中会有如下内容:

    4.修改package.js的配置,把

    "scripts":

    {

        "test": "echo \"Error: no test specified\" && exit 1"

      }

    改为

    "scripts":

    {

    "test": "echo \"Error: no test specified\" && exit 1",

    "serve": "nodemon server.js",

      }

    5.在graphql-demo目录下,新建主程序文件:server.js,内容如下,你直接拷贝一下即可。

    const mongoose = require('mongoose')

    mongoose

    .connect('mongodb://localhost:27017/graphql', { useNewUrlParser: true })

    .then(() => {

    console.log('OK!', 'Mongoose Connected.', 'Version:', mongoose.version)

    const bodyParser = require('body-parser')

    const app = require('express')()

    // 使用 body-parser 中间件

    app.use(bodyParser.urlencoded({ extended: false }))

    app.use(bodyParser.json())

    // // 引入 REST API 业务接口

    // app.use('/api/diseases', require('./routes/diseases'))

    // // 引入 GraphQL 业务接口

    // // 本接口为测试使用

    // app.use('/api/graphql/test', require('express-graphql')({

    // schema: require('./graphql/schemas/RootSchema'),

    // graphiql: true,

    // }))

    // // 本接口为正式使用

    // app.use('/api/graphql', require('express-graphql')({

    // schema: require('./graphql/schemas/RootSchema'),

    // graphiql: false,

    // }))

    const html = `

    <!DOCTYPE

    html>

    <head>

    <title>

    接口服务

    </title>

    </head>

    <br><br><br><br><br>

    <center>

    <h1>服务正常</h1>

    <h1>感谢使用</h1>

    <h1><font

    color="red">大仙出游</font></h1>

    </center>

    `

    //

    测试消息

    app.get('/', (req, res) => res.send(html))

    // 监听服务

    const host = '0.0.0.0'

    const port = 3001

    app.listen(port, host, () => { console.log(`Server listening on http://localhost:${port} http://${host}:${port}`)

    })

    })

    .catch((err) => {

    console.log(err)

    })

    6.测试程序能否正常运行:终端里执行:npm run serve,出现

    OK! Mongoose Connected. Version: 5.5.2

    Server listening on http://localhost:3001 http://0.0.0.0:3001

    说明正常,打开浏览器,输入http://localhost:3001并回车,出现

    说明服务正常。

    三、开发 REST API 项目

    1、新建目录models,用于存放模型,在目录内创建文件,名为Disease.js,定义集合结构,并编辑内容为:

    const mongoose = require('mongoose')

    const Schema = mongoose.Schema

    // Create Schema

    const ObjectSchema = new Schema({

    code: {

    type: String,

    required: true

    },

    assistant: {

    type: String

    },

    name: {

    type: String,

    required: true

    }

    })

    module.exports = Disease = mongoose.model('base.diseases', ObjectSchema)

    2、新建目录routes,用于存放路由文件,在目录内创建文件名,为diseases.js,实现相关路由,并编辑内容为:

    // @POST & GET & PUT & DELETE => CRUD

    const express = require('express')

    const router = express.Router()

    const object = require('../models/Disease')

    router.get(

    '/test',

    (req, res) => {

    res.json('OK')

    }

    )

    router.get(

    '/',

    (req, res) => {

    object

    .find()

    .then(data => {

    if (!data)

    {

    res.status(404).json({ msg: '未查到数据,请先添加!' })

    } else {

    res.json(data)

    }

    })

    .catch(err => res.status(404).json(err))

    }

    )

    router.get(

    '/:id',

    (req, res) => {

    const id = req.params.id

    console.log(id)

    object

    .findOne({ _id: id })

    .then(data => {

    if (!data)

    {

    res.status(404).json({ msg: `未查到 ${id}数据` })

    } else {

    res.json(data)

    }

    })

    .catch(err => res.status(404).json(err))

    }

    )

    3、测试REST路由能否正常使用,在server.js中,把下面的

    // // 引入 REST API 业务接口

    // app.use('/api/diseases', require('./routes/diseases'))

    取消注释,会发现终端窗口自动编译并重启服务,然后在浏览器中输入:http://localhost:3001/api/diseases,将会获取所有数据,你从网页上复制一个_id值,再输入:http://localhost:3001/api/diseases/5c8d18e4e905ba32d039cd8f,会获取单个数据。说明路由正常

    四、开发graphql项目

    1、在graphql-demo目录下新建目录graphql,在graphql目录下新建types目录,用于存放类型文件。在types目录中新建Disease.js文件,内容如下:

    const {

    GraphQLObjectType,

    GraphQLString

    } = require('graphql')

    const objectType = new GraphQLObjectType({

    name: 'Disease',

    fields: {

    _id: {

    type: GraphQLString

    },

    code: {

    type: GraphQLString

    },

    assistant: {

    type: GraphQLString

    },

    name: {

    type: GraphQLString

    }

    }

    })

    module.exports = objectType

    2、在graphql-demo目录下的graphql目录下新建schemas目录,和types同级,用于存放架构文件。在schemas目录中新建RootSchema.js文件,内容如下

    const objectDiseaseModel = require('../../models/Disease')

    const objectDiseaseType = require('../types/Disease')

    const {

    GraphQLObjectType,

    GraphQLString,

    GraphQLInt,

    GraphQLList,

    GraphQLSchema

    } = require('graphql')

    const rootSchema = new GraphQLObjectType({

    name: 'root',

    fields: {

    getDisease: {

    type: objectDiseaseType,

    args: {

    id: { type: GraphQLString }

    },

    async resolve(parent, args)

    {

    return await objectDiseaseModel.findOne({ "_id": args.id })

    }

    },

    getDiseases: {

    type: GraphQLList(objectDiseaseType),

    async resolve(parent, args)

    {

    return await objectDiseaseModel.find({})

    }

    },

    getDiseasesByPagesAndSizes: {

    type: GraphQLList(objectDiseaseType),

    args: {

    pages: { type: GraphQLInt, defaultValue: 1 },

    sizes: { type: GraphQLInt, defaultValue: 10 }

    },

    async resolve(parent, args)

    {

    return await objectDiseaseModel

    .find()

    .sort({ code: 1 })

    .skip((args.pages - 1)

    * args.sizes)

    .limit(args.sizes)

    }

    },

    }

    })

    module.exports = new GraphQLSchema({ query: rootSchema })

    3、测试路由能否正常使用,在server.js中的

    // // 引入 GraphQL 业务接口

    // // 本接口为测试使用

    // app.use('/api/graphql/test', require('express-graphql')({

    // schema: require('./graphql/schemas/RootSchema'),

    // graphiql: true,

    // }))

    // // 本接口为正式使用

    // app.use('/api/graphql', require('express-graphql')({

    // schema: require('./graphql/schemas/RootSchema'),

    // graphiql: false,

    // }))

    取消注释,会发现命令行窗口自动编译并重启服务,然后在浏览器中输入:http://localhost:3001/api/graphql/test,出现:

    说明路由正常。单击右边的Docs,出现:

    单击红色的query右边的root,出现:

    然后在最左边的框中输入:{

      getDiseasesByPagesAndSizes(pages:1,sizes:5){

        code

      }

    }

    然后单击运行,出现:

    再次编辑左边的内容,再执行,出现:

    说明服务正常,你再加个assistant试下效果:

    说明,查询的字段,可以根据实际需要进行自定义了。同理添加其它服务即可。

    五、在第三方或当前应用程序中调用graphql,本文中将使用EJS引擎,并且在当前项目中实现

    1.安装EJS依赖包,终端执行:npm i ejs

    2.在根目录下创建views目录,在views目录下创建test.ejs,内容如下:(error.ejs,自己写吧)

    <!DOCTYPE html>

    <html>

    <head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width,

    initial-scale=1.0">

    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>GraphQL

    Test</title>

    </head>

    <body>

    <h1>GraphQL

    Test</h1>

    <h2>Author:<%=author%></h2>

    <h2>Message:<%=message%></h2>

    <%if(disease){%>

    <p>disease.code:<%=disease.code%></p>

    <p>disease.name:<%=disease.name%></p>

    <%}%>

    <%if(diseasesplit){%>

    <h1>Disease

    Array</h1>

    <ul>

    <%

    diseasesplit.forEach((disease)=>{ %>

    <li><%=disease._id%>

    - <%=disease.code%>

    - <%=disease.name%></li>

    <%

    }) %>

    </ul>

    <%}%>

    </body>

    </html>

    3.在const html上边增加如下代码

    // 测试接口,注意get参数用反引号,其中不要有空格,否则会有%编码,id的值要从数据库中找一个真实存在的即可

    app.set('view engine', 'ejs')

    const axios = require('axios')

    app.get(

    '/test',

    (req, res) => {

    axios

    .get(`http://localhost:3001/api/graphql/?query={getDisease(id:"5c8d18e4e905ba32d039cd7d"){code,name}getDiseasesByPagesAndSizes(pages:2,sizes:5){_id,code,name}}`)

    .then((response) => {

    console.log(response.data.data.getDisease)

    console.log(response.data.data.getDiseasesByPagesAndSizes)

    res.render('test',

    { author: 'Daisen

    Travel', message: 'Hello

    there!', disease: response.data.data.getDisease, diseasesplit: response.data.data.getDiseasesByPagesAndSizes })

    })

    .catch((error) => {

    console.log(error)

    res.render('error',

    { error })

    })

    })

    然后在浏览器输入地址:http://localhost:3001/test,在控制台将看到:

    说明调用成功。看到页面

    有数据,说明一切OK了!

    再添加一个根据id查询的,代码如下:

    app.get(

    '/test/:id',

    (req, res) => {

    const { id } = req.params

    axios

    .get(`http://localhost:3001/api/graphql/?query={getDisease(id:"${id}"){code,name}getDiseasesByPagesAndSizes(pages:2,sizes:5){_id,code,name}}`)

    .then((response) => {

    console.log(response.data.data.getDisease)

    res.render('test',

    { author: 'Daisen

    Travel', message: 'Hello

    there!', disease: response.data.data.getDisease, diseasesplit: response.data.data.getDiseasesByPagesAndSizes })

    })

    .catch((error) => {

    console.log(error)

    res.render('error',

    { error })

    })

    })

    浏览器调用:http://localhost:3001/test/5c8d18e4e905ba32d039c84f,如下界面:

    再添加一个分页的,这次只查分页数据了,代码如下:

    app.get(

    '/test/:pages/:sizes',

    (req, res) => {

    const { pages, sizes } = req.params

    axios

    // .get(`http://localhost:3001/api/graphql/?query={getDisease(id:"5c8d18e4e905ba32d039cd7d"){code,name}getDiseasesByPagesAndSizes(pages:${pages},sizes:${sizes}){_id,code,name}}`)

    .get(`http://localhost:3001/api/graphql/?query={getDiseasesByPagesAndSizes(pages:${pages},sizes:${sizes}){_id,code,name}}`)

    .then((response) => {

    // console.log(response.data.data.getDisease)

    res.render('test',

    { author: 'Daisen

    Travel', message: 'Hello

    there!', disease: response.data.data.getDisease, diseasesplit: response.data.data.getDiseasesByPagesAndSizes })

    })

    .catch((error) => {

    console.log(error)

    res.render('error',

    { error })

    })

    })

    浏览器调用:http://localhost:3001/test/4/10,界面如下:

    总结,GraphQL是一个非常灵活的查询,随时适应需求变化,再也不用为无休止的需求而烦恼了!立刻马上转向GraphQL吧!

    祝您成功!

    相关文章

      网友评论

          本文标题:Visual Studio Code开发基于Nodejs的RES

          本文链接:https://www.haomeiwen.com/subject/milnwqtx.html