express graphQL 开发前端中间件

安装前置依赖

javascript 复制代码
 npm i express
 // 转化es 
 npm i babel-preset-env babel-cli babel-preset-stage-0
 // 添加watch
 npm i -D nodemon
 // 添加graphql
 npm i graphql graphql-http

添加启动命令

javascript 复制代码
"start": "nodemon index.js --exec babel-node --presets env stage-0"

创建入口文件

在根目录下创建index.js

javascript 复制代码
import express from 'express'; // yarn add express

const app = express();

app.listen({ port: 4000 });

json-server可以模拟接口

以下为模拟的数据,学生的基本信息和基本学习成绩

javascript 复制代码
{
  "user": [
    {
      "id": 1,
      "name": "张三",
      "age": "30",
      "gender": 1
    },
    {
      "id": 2,
      "name": "李四",
      "age": "23",
      "gender": 0
    }
  ],
  "grade": [
    {
      "id": 1,
      "Language": 53,
      "Maths": 100,
      "science": 60
    },
    {
      "id": 2,
      "Language": 39,
      "Maths": 40,
      "science": 34
    }
  ]
}

/**
 package.json 添加命令,来创建mock接口   
 分别为 http://localhost:3300/user 和 http://localhost:3300/grade
**/
"json-server": "json-server --watch ./mock/index.json --port 3300"

创建query请求

假设要将两个接口合并成一个,查询所有学生以及他们对应的成绩

./router下创建query.js

javascript 复制代码
import axios from 'axios'
// 引入所需的类型,graphQL只能用他自己的类型
import {
  GraphQLObjectType,
  GraphQLString,
  GraphQLList,
  GraphQLInt,
  GraphQLInputObjectType
} from 'graphql';

// 学生基础信息的类型
const userArgs = {
  id: {type: GraphQLInt},
  name: {type: GraphQLString},
  age: {type: GraphQLString},
  gender: {type: GraphQLInt}
}

// 请求时入参的类型声明
const queryParamsType = new GraphQLInputObjectType({
  name: 'queryParamsType',
  fields: userArgs
})

// 返回成绩的声明
const GradeType = new GraphQLObjectType({
  name: 'GradeType',
  fields: {
    id: {type: GraphQLInt},
    Language: {type: GraphQLInt},
    Maths: {type: GraphQLInt},
    science: {type: GraphQLInt}
  }
})

// 返回的学生声明
const UserType = new GraphQLObjectType({
  name: 'UserType',
  fields: {
    id: {type: GraphQLInt},
    name: {type: GraphQLString},
    age: {type: GraphQLString},
    gender: {type: GraphQLInt},
    // 可以直接将要的数据放入声明里
    grade: {
      type: GradeType,
      // 直接通过resolve进行数据请求 parent是父级返回的数据
      resolve(parent) {
        return axios({
          url: `http://localhost:3300/grade`,
          params: { id: parent.id } // 在请求中带上参数
        }).then(result => {
          if(Array.isArray(result.data)){
            return result.data[0]
          }
          return result.data;
        });
      },
    }
  }
})


// 声明的query类型,并把他暴露出去
export const QueryType = new GraphQLObjectType({
  name: 'Query',
  fields: {
    user: {
      type: new GraphQLList(UserType),
      // 一定要将args带上,这是入参的声明
      args: {
        queryParams: {
          type: queryParamsType
        }
      },
      resolve(obj, args){
        return axios({
          url: 'http://localhost:3300/user',
          params: args.queryParams
        }).then(result => result.data)
      },
    }
  },
})

在index.js中使用

javascript 复制代码
import express from 'express'; // yarn add express
import { createHandler } from 'graphql-http/lib/use/express';
import {QueryType} from './router/query'
import {GraphQLSchema} from "graphql/index";

const app = express();
const schema = new GraphQLSchema({
  query: QueryType,
});

app.all('/graphql', createHandler({
  schema
}));

app.listen({ port: 4000 });

此时请求时的query

javascript 复制代码
// queryParams 中可以放我们的入参
{
  user(queryParams: {}) {
    id
    name
    age
    gender
    grade {
      id
      Language
      Maths
      science
    }
  }
}

创建mutation请求

操作和query请求基本没什么区别

javascript 复制代码
const PostUserType = new GraphQLInputObjectType({
  name: 'PostUserType',
  fields: {
    name: {type: GraphQLString},
    age: {type: GraphQLString},
    gender: {type: GraphQLInt},
  }
})
export const MutationType = new GraphQLObjectType({
  name: 'Mutation',
  fields: {
    createUser: {
      type: GraphQLBoolean, 
      args: {
        postParams: { type: PostUserType}
      },
      resolve(parent, args) {
        return axios.post('http://localhost:3300/user', args.postParams)
          .then((response) => {
            return true
          })
          .catch(error => {
            // 处理错误情况
            console.error('Error creating user:', error.message);
            throw new Error('Failed to create user.');
          });
      }
    }
  }
});

然后再index.js中使用

javascript 复制代码
const schema = new GraphQLSchema({
  query: QueryType,
  mutation: MutationType
});
相关推荐
GuWenyue3 小时前
放弃云端API!一套React+WebGPU本地LLM方案,零数据上传、离线可用
前端·人工智能·前端框架
原则猫4 小时前
函数/变量提升
前端
独泪了无痕5 小时前
Vue3 Hooks使用实战解析
前端·vue.js
shawxlee6 小时前
vue3在public下封装config.js自定义配置动态数据,可在打包后直接修改,方便后端部署及后续维护
前端·javascript·经验分享·vue·团队开发·js·项目优化
用户059540174467 小时前
把记忆存储的回归测试从手工换成 Playwright + GitHub Actions,线上缺陷降低 80%
前端·css
触底反弹7 小时前
🚀 从 DOM0 级到 React 合成事件:前端事件监听的 20 年演进史
前端·react.js·面试
kyriewen7 小时前
我给前端项目的接口请求套了6层保护——才发现以前一直在裸奔
前端·javascript·面试
颜酱7 小时前
04 | 召回前置准备:搭好召回所需的四个数据库
前端·人工智能·后端
郝亚军8 小时前
如何安装webstorm、Node.js和vue CLI
前端·javascript·vue.js
IT_陈寒8 小时前
React的useEffect依赖项把我坑惨了
前端·人工智能·后端