GraphSQLミドルウェア( Node ,アポロサーバ,急行)の書き方
6259 ワード
この記事では
私は、あなたがノードに精通していると仮定します.アポロサーバ、エクスプレス、およびES 6 +構文.
私はセットアップのほとんどをスキップします、そして、あなたはすでにLaTeSQL APIがアポロサーバでセットアップしたと仮定します.では、インストールしましょう
まず、これらの関数をインポートします.
ミドルウェアフォルダにファイルを作りましょう
簡単にあなたのクッキーへのアクセスを得るために、我々がこの機能でここに着くように、あなたは
このミドルウェアがどんなミドルウェアも見つけることができないなら、我々はクライアントにAPIへのどんなアクセスも得ることを妨げるべきです.私たちはアポロサーバを定義済みのエラーの非常に有用なコレクションを使用することができます.
我々は、スキップします
それで、それは1をカバーします.と2 .我々のtodosから、3に移りましょう.アポロARGSにユーザーの詳細を追加します.これにより、指定されたリゾルバのユーザの詳細にアクセスすることができます.
この関数に渡される4つの引数はすべてのミドルウェアに渡されます. 前に来るコード の後のどんなコードでも レゾルバに渡す引数を選択できます.この場合、ユーザオブジェクトをargsに追加したので、レゾルバにアクセスできます この時点で、おそらくどのようにリゾルバは、このミドルウェアを使用するかを選択する疑問があります.これは私たちのtodosからポイント番号4に私たちをもたらします.
リゾルバ名をキーとし、ミドルウェア関数を値としてエクスポートする必要があります.GraphSQLミドルウェアパッケージは、この関数が指定されたレゾルバで実行されることを保証するためにいくつかの魔法を働かせます.
このため、引数としてレゾルバの配列、およびミドルウェア機能を受け入れるヘルパー関数を書きました.これは、配列としてレゾルバを使用して1つのオブジェクトを返します.以下はヘルパー関数の使い方です.
今、あなた自身のカスタムミドルウェアを書く準備が整いました.楽しい!
P . S .このミドルウェアのためにJestを使って統合テストを書く方法に興味がありますか?カミングスーン😎
Node.js
apollo-server-express
とgraphql-middleware
パッケージ.私は、あなたがノードに精通していると仮定します.アポロサーバ、エクスプレス、およびES 6 +構文.
私はセットアップのほとんどをスキップします、そして、あなたはすでにLaTeSQL APIがアポロサーバでセットアップしたと仮定します.では、インストールしましょう
graphql-middleware
and graphql-tools
.yarn add graphql-middleware graphql-tools
// or
npm install graphql-middleware graphql-tools
次に、インデックスファイルを使用してミドルウェアフォルダを作成します.もちろん、これはあなたが好きな構造です.mkdir src/middleware && touch src/middleware/index.js
現在、我々はミドルウェアをアポロサーバ建設者に加えなければなりません.だから、あなたのサーバーに移動します.JSファイル(またはアポロのインスタンスを作成する場所).まず、これらの関数をインポートします.
import { applyMiddleware } from 'graphql-middleware';
import { makeExecutableSchema } from 'graphql-tools';
次にアポロサーバのインスタンスに追加します.import resolvers from './resolvers' // returns array of resolvers
import middleware from './middleware' // returns array of middelware
// this combines all of the resolvers
const executableSchema = makeExecutableSchema({ typeDefs: schema, resolvers });
const schemaWithMiddleware = applyMiddleware(executableSchema, ...middleware);
const server = new ApolloServer({
playground: true,
typeDefs: schema,
resolvers,
context: async ({ req, res }) => ({ req, res }), // now we can access express objects from apollo context arg
schema: schemaWithMiddleware, // add this property
});
さて、セットアップは完了しました、現在、我々は若干のミドルウェアを書く準備ができています.この例では、サーバーに着信要求をチェックするいくつかのミドルウェアを作成します.ミドルウェアフォルダにファイルを作りましょう
touch src/middleware/getUserFromCookie.js
さて、忘れないうちにこのファイルをミドルウェア/インデックスにインポートしましょう.jsファイルimport getUserFromCookie from './getUserFromCookie';
export default [getUserFromCookie];
このモジュールの計画を立てましょう.私はよくコメントを書きます.// TODO
// 1. get session cookie from express request object
// 2. use session id to get user details
// 3. add user to Apollo args
// 4. specify which resolvers to add the middleware to
さあ準備ができました.番号1から始めましょう.async function getUserFromCookie(req) {
try {
const { clientSession } = req.cookies; // requires cookie-parser middleware
if (!clientSession) {
throw new Error('session cookie does not exist');
}
return await getUser(clientSession); // get user details from Database
} catch (error) {
throw new AuthenticationError(`Cannot get user from cookie: \n ${error}`);
}
}
何が起こっているのですか.どこでreq
Param !ベアーウィズミー.この関数を後で呼び出し、この引数を渡します.簡単にあなたのクッキーへのアクセスを得るために、我々がこの機能でここに着くように、あなたは
cookie-parser
ミドルウェアパッケージ.この品はこれから出ます.このミドルウェアがどんなミドルウェアも見つけることができないなら、我々はクライアントにAPIへのどんなアクセスも得ることを妨げるべきです.私たちはアポロサーバを定義済みのエラーの非常に有用なコレクションを使用することができます.
我々は、スキップします
getUser
この記事では、APIのユーザーデータの取得方法について説明します.それで、それは1をカバーします.と2 .我々のtodosから、3に移りましょう.アポロARGSにユーザーの詳細を追加します.これにより、指定されたリゾルバのユーザの詳細にアクセスすることができます.
async function addUserToArgs(resolve, parent, args, context, info) {
const user = await getUserFromCookie(context.req);
const argsWithUser = { user, ...args };
return resolve(parent, argsWithUser, context, info);
}
これがミドルウェア機能だ.注意すべき点resolve
リゾルバが実行される前に実行されますresolve
関数は、リゾルバが実行された後に実行されますargs.user
リゾルバ名をキーとし、ミドルウェア関数を値としてエクスポートする必要があります.GraphSQLミドルウェアパッケージは、この関数が指定されたレゾルバで実行されることを保証するためにいくつかの魔法を働かせます.
export default {
Query: {
getUserDetails: addUserToArgs,
},
Mutation: {
updateUserDetails: addUserToArgs,
},
};
OK、私たちはほとんど完了です!しかし、この時点では、すべてのリゾルバ(または多くのレゾルバ)にいくつかのミドルウェアを追加したい場合は、これはすぐに退屈になり、非常に困難になるAPIの成長として維持する.このため、引数としてレゾルバの配列、およびミドルウェア機能を受け入れるヘルパー関数を書きました.これは、配列としてレゾルバを使用して1つのオブジェクトを返します.以下はヘルパー関数の使い方です.
// import array of objects with Query and Mutaion properties
import resolvers from '../../resolvers';
import addMiddlewareToResolvers from './addMiddlewareToResolvers';
// pass array of resolvers and middleware function
export default addMiddlewareToResolvers(resolvers, addUserToArgs);
/*
return {
Query: {
getUserDetails: addUserToArgs
// rest of the queries
},
Mutation: {
updateUserDetails: addUserToArgs
// rest of the mutations
}
}
*/
そしてここに関数があります.誰でもこれを単純化することができて、それをより読みやすいようにするならば、ちょっと複雑です、私はそれを見たいです!import { ApolloError } from 'apollo-server-express'
// returns object with resolver names as keys, and middleware function as value
export default function addMiddleware(
resolvers,
middlewareFunction,
) {
try {
return resolvers?.reduce(
(a, c) => buildResolverObject(a, c, middlewareFunction),
{},
)
} catch (error) {
throw new ApolloError(`Error in addMiddlewareToResolvers - ${error}`)
}
}
function buildResolverObject(
accumulator: any,
{ Query, Mutation },
middlewareFunction: any,
) {
const queryProperties = getResolverProperties(Query, middlewareFunction)
const mutationProperties = getResolverProperties(Mutation, middlewareFunction)
return {
Query: {
...accumulator.Query,
...queryProperties,
},
Mutation: {
...accumulator.Mutation,
...mutationProperties,
},
}
}
function getResolverProperties(resolverObject = {}, middlewareFunction) {
const keys = Object.keys(resolverObject)
const properties = keys.map((key) => ({ [key]: middlewareFunction }))
return properties.reduce((a, c) => ({ ...a, ...c }), {})
}
それで🎉今、あなた自身のカスタムミドルウェアを書く準備が整いました.楽しい!
P . S .このミドルウェアのためにJestを使って統合テストを書く方法に興味がありますか?カミングスーン😎
Reference
この問題について(GraphSQLミドルウェア( Node ,アポロサーバ,急行)の書き方), 我々は、より多くの情報をここで見つけました https://dev.to/seancwalsh/how-to-write-graphql-middleware-node-apollo-server-express-2h87テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol