Я хочу использовать операторы журнала morgantiny для всех моих маршрутов, кроме конечных точек graphql. Я использую экспресс и Apollo 2, и мне не удалось заставить промежуточное ПО работать с экспрессом. Как показывает пример кода, я могу установить промежуточное ПО для всего экспресс-приложения, но я хочу ограничить область действия.
Моей первой попыткой было создать express.router() и передать маршрутизатор на apolloServer.applyMiddleware, но, похоже, это не сработало.
Я хочу использовать morgan, но я также хочу использовать промежуточное программное обеспечение express-jwt.
import morgan from 'morgan'
import { mergeSchemas } from 'graphql-tools'
import { ApolloServer } from 'apollo-server-express'
import assessmentSchema from './assessment/schema'
import AssessmentAPI from './assessment/dataSource'
import userSchema from './user/schema'
import UserAPI from './user/dataSource'
/**
* Installs apollo-server to handle requests under `path`
* @param {*} app Express instance
* @param {*} path route path, like '/graphql'
*/
export const createApi = (app, path) => {
const dataSources = () => ({
assessmentAPI: new AssessmentAPI({ store: 'intentionally undefined' }),
userAPI: new UserAPI()
})
const schema = mergeSchemas({
schemas: [assessmentSchema, userSchema]
})
morgan.token('graphql-query', req => {
const { operationName } = req.body
return `GRAPHQL: Operation Name: ${operationName}`
})
// TODO: Add custom logging middleware for GraphQL queries/mutations
// The next line would add middleware to all of express, but I only want this style of logging for graphQL
/*** Question is about the following line ***/
// app.use(morgan(':graphql-query'))
const apolloServer = new ApolloServer({ schema, dataSources })
apolloServer.applyMiddleware({ app, path })
}
Спасибо!
Я просто пробовал использовать экспресс-роутер, и он работает. gist.github.com/rohitharkhani/45d3111807a7094b73bea71c124c74 2b. Не уверен, относится ли это к другому модулю. Можете ли вы просто дважды проверить, добавили ли вы маршрутизатор в приложение?





Есть несколько хитрых способов добиться желаемого. Вместо этого вы можете использовать express.Route для регистрации промежуточного программного обеспечения на каждом маршруте, но я думаю, что вам могут потребоваться более конкретные журналы о GraphQL, а не о запросе в частности.
Доступный как обратный вызов внутри ApolloServer, он получает объект с запросом и ответом.
const myServer = new ApolloServer({
schema: ...,
context:({ req, res }) => {
// log here
}
});
Доступный как обратный вызов внутри ApolloServer, он получает ответ и запрос.
const server = new Apollo.ApolloServer({
schema: ...,
formatResponse: (res, query) => {
// log here
// notice you must return the response
return res;
},
});
Источники: formatResponse, контекст
Еще одна вещь, которую вы можете сделать, - это проверить обратный вызов morgan, совпадает ли req.path с путем /graphQL, и войти только в этой ситуации, но это очень похоже на журнал Express.Route с помощью morgan
Я согласен с тем, что это хуки, в которых код может выполняться с каждым запросом graphql (либо через context() перед запросом, либо через formatResponse() после, но ни один из них не предназначен для поддержки промежуточного программного обеспечения Express.
Что я сделал, так это добавил req к объекту контекста. Кажется, это лучший вариант, который я придумал. context: ({req, res}) => ({req, res}) Это позволяет получить доступ к экспресс-запросам / ресурсам из преобразователей графа и источника данных.
Да, я тоже думал об этом, также я отредактировал ответ, добавив еще один способ сделать это, но это то же решение, что и выше, я думаю
На данный момент ваш подход - лучший ответ, но я действительно надеялся, что существует какой-то очевидный способ использовать промежуточное программное обеспечение с Apollo Server (и я просто не знал, что это было). Возможно, кто-то еще внесет другой ответ - или, возможно, его просто невозможно.
дай мне знать, чем ты закончил
Как мне перейти next () к промежуточному программному обеспечению? Я попытался деконструировать его в контексте args, но он не определен.
С apollo server v2 очень просто использовать его только на одном маршруте. применить его как промежуточное ПО. т.е.
const app = require('express')();
const apolloServer = new ApolloServer ({
typeDefs,
resolvers
})
// then use it on a particular route
apolloServer.applyMiddleware({ app, path: '/specialUrl' });
const express = require("express");
const router = express.Router();
const { ApolloServer, gql } = require('apollo-server-express');
const server = new ApolloServer({
schema: schema,
introspection: true
});
server.applyMiddleware({ app:router });
module.exports = router;
Есть пакет npm GraphQL-маршрутизатор-ПО
Используя это, вы можете добавить промежуточное ПО уровня маршрутизатора к вашим преобразователям во многом аналогично тому, как мы это делаем в экспрессе.
Вы можете настроить свой резолвер примерно так:
import Router from 'graphql-router-ware';
import { checkPermission } from '../helpers/userhalper';
import Controller from '../controllers/page';
const resolvers = {
Query: {
singlePage: Router(Controller.singlePage)
},
Mutation: {
createPage: Router(checkPermission,Controller.create),
updatePage: Router(checkPermission,Controller.update),
}
}
export default resolvers;
За ним следует ваше промежуточное ПО:
// ....
export checkPermission=({ ctx },next)=>{
if (!ctx.user){
return next(new Error('Not logged in'));
// or throw new Error('Not logged in')
}
// some more permission checks....
return next();
};
// ....
Надеюсь, это было полезно.
Добавлен связанный комментарий на GitHub: github.com/apollographql/apollo-server/issues/…