基于上一篇的项目继续深入学习和介绍项目中如何使用GraphQl.本篇更侧重于实际项目中使用GraphQL.如果还没有了解基本的GraphQl知识和没用想要新建项目开始演练的可从
上一篇开始如何 在NodeJs搭建GraphQL service Apollo Server (1).
1.重构app.js和service.mjs
1.1 修改service.mjs
上一篇提到我们使用的是epress-generator创建的的我们nodejs的express项目.所以我们当时开辟了两个进程挂载server. Aollo Server很贴心的支持express,所以我们现在(2024/5) 可以在一个进程挂载Nodejs的epress server 和Graphql的plugin server.
在Graphql的实际项目中我们更习惯使用http,rest这种方式去发送和获取数据.首先安装一个扩展包 datasource-rest
npm i @apollo/datasource-rest
Apollo的rest扩展包可以方便我fetch数据和编写fetch的一些列有relate的操作函数.
在sercive.mjs
import { expressMiddleware } from '@apollo/server/express4';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer'
引入rest包和express的中间件包
创建express得server和设置Apollp server.并启动Apollo 的服务.
const httpServer = http.createServer(app);
// Set up Apollo Server
const server = new ApolloServer({
typeDefs,
resolvers,
plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],
});
await server.start();
1.2 创建nodejs中间件
app.use(
'/graphql',
cors(),
bodyParser.json(),
expressMiddleware(server, {
context: async () => {
const { cache } = server;
return {
dataSources: {
randomUserApi: new GetUserApi({ cache }),
},
}
}
}),
);
其中 dataScource可以理解指代的是我们rest api的api集合.
randomUserApi 这个就是我们的api的接口名称
GetUserApi: 实际rest的实体(实例)
dataSources: {
randomUserApi: new GetUserApi({ cache }),
},
因为是一个实例所以当我有N多个API的时候我还会像抽出来单独管理比较简洁
所以单独抽出这个文件
1.3 getUserApi.js
import {RESTDataSource} from '@apollo/datasource-rest'
class GetUserApi extends RESTDataSource {
constructor() {
super();
this.baseURL = "http://localhost:8001/";
}
async getUserInfor () {
const result = await this.get(`test/`)
return result.results
}
async getUserInforByName (userName) {
return await this.post(
`getUserInforByName`,
{body: {userName}},
)
}
async deleteUserInforById (id) {
return await this.delete(
`deleteUserInforById/${encodeURIComponent(id)}`
)
}
}
export default GetUserApi
这个实例类中的几个method很好理解.分别给get, post,delete使用.post的请求只是一个条件传参.Graphql的多组参数,条件参数,多表关联查询以后会讲.
baseURL:这个指向的就是我们的数据源
1.4 创建测试数据
作为demo的数据演示,我在db中加了一些测试数据,并开了一个db的server,postman看下测试的数据结构
实际的应用中db的数据源可以和Graphql的server使用同一个,例子中方便理解额外开了一个.
1.4. 创建schema& 封装typeDefs
在utils下创建一个 schema.js文件, 并声明初我们的rest api的接口名称.这里的randomeDates就是我们声明的接口名称,其中dataScourece对应NodeJs中间件中的api集合.这里的意思是调用在这个接口下返回我们getUserInfor的函数的值(getUserInfor是我们getUserApi.js中定义.
const typeDefs = `#graphql
enum LengthUnit {
METER
KILOMETER
MILE
FOOT
}
type userDatas{
username: String
dateCreate:String
id: String
length(unit: LengthUnit = METER): Float
}
type Query {
randomeDatas:[userDatas]
}
`;
const resolvers = {
Query: {
randomeDatas: (_, __, {dataSources}) =>
dataSources.randomUserApi.getUserInfor()
},
};
export {
typeDefs,
resolvers
}
回到service.mjs 引用我们的typeDefs和resolvers.最终如下
import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@apollo/server/express4';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer'
// import {startStandaloneServer} from '@apollo/server/standalone'
import http from 'http';
import cors from 'cors';
import bodyParser from 'body-parser';
import app from '../../app.js'
import {typeDefs, resolvers} from './schema.js'
import GetUserApi from './getUserApi.js'
const httpServer = http.createServer(app);
// Set up Apollo Server
const server = new ApolloServer({
typeDefs,
resolvers,
plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],
});
await server.start();
app.use(
'/graphql',
cors(),
bodyParser.json(),
expressMiddleware(server, {
context: async () => {
const { cache } = server;
return {
dataSources: {
randomUserApi: new GetUserApi({ cache }),
},
}
}
}),
);
await new Promise((resolve) => httpServer.listen({ port: 4000 }, resolve));
console.log(`
标签:const,app,Server,server,GraphQl,rest,import,js,Apollo
From: https://blog.csdn.net/EvanYYY1/article/details/139176354