简体   繁体   English

如何仅使用 Apollo Server 2 graphql 端点的快速中间件

[英]How can I use express middleware with only Apollo Server 2 graphql endpoints

I want to use morgan 's tiny log statements for all of my routes, except graphql endpoints.我想对我的所有路由使用morgantiny日志语句,除了 graphql 端点。 I'm using express and Apollo 2, and have not been able to get middleware working with express.我正在使用 express 和 Apollo 2,并且无法让中间件与 express 一起工作。 As the code sample shows, I can install middleware for the entire express app, but I want to limit the scope.如代码示例所示,我可以为整个 express 应用程序安装中间件,但我想限制范围。

My first attempt was to create an express.router() and pass the router to apolloServer.applyMiddleware , but that doesn't seem to work.我的第一次尝试是创建一个express.router()并将路由器传递给apolloServer.applyMiddleware ,但这似乎不起作用。

I want to use morgan --but I also want to use express-jwt middleware.我想使用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 })
}

Thanks!谢谢!

There are some 'Hacky' ways to achieve what you desire.有一些“Hacky”方法可以实现您的愿望。 You can use express.Route to register middlewares on each route instead, but I think that you may want more specific logs about GraphQL rather than the request in particular.您可以使用 express.Route 在每个路由上注册中间件,但我认为您可能需要关于 GraphQL 的更具体的日志,而不是特定的请求。

context()语境()

Available as a callback inside ApolloServer, it receives an object with the request and response.可用作 ApolloServer 内部的回调,它接收带有请求和响应的对象。

const myServer =  new ApolloServer({
  schema: ...,
  context:({ req, res }) => { 
    // log here
  }
});

fortmatResponse()格式响应()

Available as a callback inside ApolloServer, it receives the response and the query.可作为 ApolloServer 内部的回调,它接收响应和查询。

const server = new Apollo.ApolloServer({
  schema: ...,
  formatResponse: (res, query) => {
    // log here

    // notice you must return the response
    return res;
  },
});

Sources: formatResponse , context来源: formatResponse上下文

Edit编辑

Another thing you can do is on morgan callback check if the req.path matches with the /graphQL path, and log only in that situation but this is much the same as log an Express.Route with morgan您可以做的另一件事是在 morgan 回调中检查 req.path 是否与/graphQL路径匹配,并仅在这种情况下登录,但这与使用摩根登录 Express.Route 非常相似

With apollo server v2, its really simple to use it only on a single route.使用 apollo server v2,仅在单个路由上使用它非常简单。 apply it as middleware.将其用作中间件。 ie IE

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;

There is a npm package GraphQL-Router-Ware有一个 npm 包GraphQL-Router-Ware

Using this you can add router level middlewares to your resolvers in a much similar way like we do in express.使用它,您可以像我们在 express 中所做的那样,将路由器级别的中间件添加到您的解析器中。

You can setup your resolver something like this :您可以像这样设置解析器:

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;

Followed by your middleware :其次是您的中间件:

// ....
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();
};
// ....

Hope this was helpful.希望这是有帮助的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我可以在没有 Apollo Server 的情况下使用 Apollo Client 吗? 我有一个普通的 GraphQl express 服务器并且想要与前端 ReactJS 集成 - I can use Apollo Client without Apollo Server? I have a plain GraphQl express server and want to integrate with front-end ReactJS 如何使用 Apollo Express 仅为 Graphql 后端中的特定解析器设置中间件? - how to set a middleware only for a specific resolver in Graphql backend using Apollo Express? 如何在Apollo GraphQL服务器之上放置Express REST层? - How can I put an Express REST layer on top of an Apollo GraphQL server? Apollo-Server v2中间件之后如何使用Express中间件? - How to use Express middleware after Apollo-Server v2 middleware? 我怎样才能让`apollo server` 与 graphql schemaObject 一起工作? - How can I make `apollo server` to work with graphql schemaObject? 如何在我的 Apollo GraphQL 服务器上调试 memory 泄漏? - How can I debug a memory leak on my Apollo GraphQL server? Apollo Server Express + GraphQL关系 - Apollo Server Express + GraphQL relationships Node express 服务器仅对 localhost 使用中间件 - Node express server use middleware only for localhost Apollo Server - GraphQL 错误:只能有一种名为“查询”的类型 - Apollo Server - GraphQL Error: There can be only one type named "Query" 如何在graphql中使用中间件 - How to use middleware in graphql
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM