git clone https://github.com/apollographql/fullstack-tutorial.gitcd start/server && npm install- 修改文件
start/server/src/schema.js
const { gql } = require('apollo-server');
const typeDefs = gql `
type Launch {
id: ID!
site: String
mission: Mission
rocket: Rocket
isBooked: Boolean!
}
type Rocket {
id: ID!
name: String
type: String
}
type User {
id: ID!
email: String!
trips: [Launch]!
}
type Mission {
name: String
missionPatch(size: PatchSize): String
}
type TripUpdateResponse {
success: Boolean!
message: String
launches: [Launch]
}
enum PatchSize {
SMALL
LARGE
}
type Query {
launches: [Launch] !
launch(id: ID!): Launch
me: User
}
type Mutation {
bookTrips(launchIds: [ID]!): TripUpdateResponse!
cancelTrip(launchId: ID!): TripUpdateResponse!
login(email: String): String
}
`;
module.exports = typeDefs;- 修改文件
start/server/src/index.js
const { ApolloServer } = require('apollo-server');
const typeDefs = require('./schema');
const server = new ApolloServer({ typeDefs });
server.listen().then(({ url }) => {
console.log(`sevrer ready at url : ${url}`);
});-
在
start/server目录下执行npm start -
就可以访问
http://localhost:4000/ -
Apollo会判断
NODE_ENV是否为production,如果是,则会关闭 introspect 功能
数据源可以是 database、service、API等等
- 配置数据源:修改
start/server/src/datasources/launch.js文件
const { RESTDataSource } = require('apollo-datasource-rest');
class LaunchAPI extends RESTDataSource {
constructor() {
super();
this.baseURL = 'https://api.spacexdata.com/v2/';
}
}
module.exports = LaunchAPI;- 写方法调用 REST 数据,继续修改
start/server/src/datasources/launch.js文件
const { RESTDataSource } = require('apollo-datasource-rest');
class LaunchAPI extends RESTDataSource {
constructor() {
super();
this.baseURL = 'https://api.spacexdata.com/v2/';
}
async getAllLaunches() {
const response = await this.get('launches');
return Array.isArray(response)
? response.map(launch => this.launchReducer(launch))
: [];
}
}
module.exports = LaunchAPI;- 处理 REST 数据烦恼会,继续修改
start/server/src/datasources/launch.js文件
const { RESTDataSource } = require('apollo-datasource-rest');
class LaunchAPI extends RESTDataSource {
constructor() {
super();
this.baseURL = 'https://api.spacexdata.com/v2/';
}
async getAllLaunches() {
const response = await this.get('launches');
return Array.isArray(response)
? response.map(launch => this.launchReducer(launch))
: [];
}
// 数据转换
launchReducer(launch) {
return {
id: launch.flight_number || 0,
cursor: `${launch.launch_date_unix}`,
site: launch.launch_site && launch.launch_site.site_name,
mission: {
name: launch.mission_name,
missionPatchSmall: launch.links.mission_patch_small,
missionPatchLarge: launch.links.mission_patch,
},
rocket: {
id: launch.rocket.rocket_id,
name: launch.rocket.rocket_name,
type: launch.rocket.rocket_type,
},
};
}
async getLaunchById({ launchId }) {
const response = await this.get('launches', { flight_number: launchId });
return this.launchReducer(response[0]);
}
getLaunchesByIds({ launchIds }) {
return Promise.all(
launchIds.map(launchId => this.getLaunchById({ launchId })),
);
}
}
module.exports = LaunchAPI;-
官方示例中,
start/server/src/datasources/user.js文件,会导出UserAPI模块,该模块初始化时,需要传入store。 -
store是数据库操作相关的API,在后续的章节中,store是由createStore创建而来。 -
createStore是从start/server/src/utils.js中导出的,该模块中定义了数据库的相关操作。
修改 start/server/src/index.js文件如下
const { ApolloServer } = require('apollo-server');
const typeDefs = require('./schema');
const LaunchAPI = require('./datasources/launch');
const UserAPI = require('./datasources/user');
// 这里定义了sqlite操作的相关API,在后续章节中介绍
const store = createStore();
const server = new ApolloServer({
typeDefs,
dataSources: () => ({
launchAPI: new LaunchAPI(),
userAPI: new UserAPI({ store })
})
});
server.listen().then(({ url }) => {
console.log(`sevrer ready at url : ${url}`);
});- 方法签名描述
// 暂时无法解释
// parent:
// args:
// context:
// info
fieldName: (parent, args, context, info) => data;- 修改文件:
start/server/src/resolvers.js
module.exports = {
Query: {
launches: (_, __, { dataSources }) => dataSources.launchAPI.getAllLaunches(),
launch: (_, { id }, { dataSources }) => dataSources.launchAPI.getLaunchById({ launchId: id }),
me: (_, __, { dataSources }) => dataSources.userAPI.findOrCreateUser()
}
};const { ApolloServer } = require('apollo-server');
const typeDefs = require('./schema');
const { createStore } = require('./utils');
const resolvers = require('./resolvers');
const LaunchAPI = require('./datasources/launch');
const UserAPI = require('./datasources/user');
const store = createStore();
const server = new ApolloServer({
typeDefs,
resolvers,
dataSources: () => ({
launchAPI: new LaunchAPI(),
userAPI: new UserAPI({ store })
})
});
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});未完待续...
- 初始化参数:
typeDefs: 定义了scheme,类似于类型和方法声明
resolvers:定义了实现,一般typeDefs定义的方法,需要在resolvers中实现
dataSources:用于初始化数据源,比如调用各个系统的API,操作数据库等等
playground:是否开启graphQL的playground
introspection:是否开启模式自省,如果关闭的话,那么在playground中就无法查看scheme,但是playground仍然可用
context: 当前请求的上下文
mocks:是否开启模拟数据
schema:它将覆盖typeDefs、resolvers
debug:是否开启debug模式
cors:是否支持跨域请求
- 方法
listen:开启server,并可以设置监听的端口号
