Вообще говоря, я обнаружил, что лучший способ сохранить мой код организованным - это поместить всю бизнес-логику в другое место, инициализировать в объект context
. Если вы используете graphql-js
напрямую (он будет настроен иначе, если вы используете что-то вроде apollo-server
, но context
все еще подходит для этого):
выдержка из graphql.js
(загрузчики данных - это логика SRP)
const { graphql } = require('graphql');
const dataloaders = require('./dataloaders');
const typeDefs = require('./type-definitions')
const schema = require('./schema')
exports.query = (whatever, args) => {
const context = {};
context.requestId = 'uuid-something';
context.loaders = dataloaders.initialize({ context });
return graphql(schema, query, null, context)
}
схема.js выдержка
const RootQueryType = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
ownerData: {
type: OwnerType,
description: 'Get all owners',
args:{key: {type: GraphQLString} },
resolve: (obj, args, context) => {
const key = args.key;
return context.loaders.owner({ key });
}
}
}
});
выдержка dataloaders.js
exports.initialize = ({ context }) => {
return {
owner({ key }) {
const url = 'http://localhost:6001/api/.../' + key
return fetch(url, { headers: { requestId: context.requestId }})
.then(response => {
return response.json()
})
.then(json => {
return transform(json)
})
.catch(err => {
console.trace(err)
});
}
}
};
В дополнение к лучшей организации кода, выполнение этого способа позволяет упростить тестирование, поскольку ваши распознаватели не нуждаются во внешних зависимостях. Таким способом вы можете внедрить свои зависимости, предварительно загрузив контекст тем, что вы хотите для тестирования, и вы можете обрабатывать бизнес-логику, к которой относится бизнес-логика.
Инициализация вашей бизнес-логики с контекстом запроса также позволяет вам настраивать функциональность на основе запроса: requestId (как я показал), контроль доступа и т. Д.