在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:graphql-community/koa-graphql开源软件地址:https://github.com/graphql-community/koa-graphql开源编程语言:TypeScript 84.8%开源软件介绍:GraphQL Koa MiddlewareCreate a GraphQL HTTP server with Koa. Port from express-graphql. Installation
TypeScriptThis module includes a TypeScript declaration file to enable auto complete in compatible editors and type information for TypeScript projects. Simple SetupMount const Koa = require('koa');
const mount = require('koa-mount');
const { graphqlHTTP } = require('koa-graphql');
const app = new Koa();
app.use(
mount(
'/graphql',
graphqlHTTP({
schema: MyGraphQLSchema,
graphiql: true,
}),
),
);
app.listen(4000); Setup with Koa RouterWith const Koa = require('koa');
const Router = require('@koa/router');
const { graphqlHTTP } = require('koa-graphql');
const app = new Koa();
const router = new Router();
router.all(
'/graphql',
graphqlHTTP({
schema: MyGraphQLSchema,
graphiql: true,
}),
);
app.use(router.routes()).use(router.allowedMethods()); Setup with Koa v1For Koa 1, use koa-convert to convert the middleware: const koa = require('koa');
const mount = require('koa-mount'); // [email protected]
const convert = require('koa-convert');
const { graphqlHTTP } = require('koa-graphql');
const app = koa();
app.use(
mount(
'/graphql',
convert.back(
graphqlHTTP({
schema: MyGraphQLSchema,
graphiql: true,
}),
),
),
); Setup with Subscription Supportconst Koa = require('koa');
const mount = require('koa-mount');
const { graphqlHTTP } = require('koa-graphql');
const typeDefs = require('./schema');
const resolvers = require('./resolvers');
const { makeExecutableSchema } = require('graphql-tools');
const schema = makeExecutableSchema({
typeDefs: typeDefs,
resolvers: resolvers,
});
const { execute, subscribe } = require('graphql');
const { createServer } = require('http');
const { SubscriptionServer } = require('subscriptions-transport-ws');
const PORT = 4000;
const app = new Koa();
app.use(
mount(
'/graphql',
graphqlHTTP({
schema: schema,
graphiql: {
subscriptionEndpoint: `ws://localhost:${PORT}/subscriptions`,
},
}),
),
);
const ws = createServer(app.callback());
ws.listen(PORT, () => {
// Set up the WebSocket for handling GraphQL subscriptions.
new SubscriptionServer(
{
execute,
subscribe,
schema,
},
{
server: ws,
path: '/subscriptions',
},
);
}); OptionsThe
In addition to an object defining each option, options can also be provided as
a function (or async function) which returns this options object. This function
is provided the arguments The app.use(
mount(
'/graphql',
graphqlHTTP(async (request, response, ctx, graphQLParams) => ({
schema: MyGraphQLSchema,
rootValue: await someFunctionToGetRootValue(request),
graphiql: true,
})),
),
); HTTP UsageOnce installed at a path,
GraphQL will first look for each parameter in the query string of a URL:
If not found in the query string, it will look in the POST request body. If a previous middleware has already parsed the POST body, the If the POST body has not yet been parsed,
Combining with Other koa MiddlewareBy default, the koa request is passed as the GraphQL This example uses const Koa = require('koa');
const mount = require('koa-mount');
const session = require('koa-session');
const { graphqlHTTP } = require('koa-graphql');
const app = new Koa();
app.keys = ['some secret'];
app.use(session(app));
app.use(function* (next) {
this.session.id = 'me';
yield next;
});
app.use(
mount(
'/graphql',
graphqlHTTP({
schema: MySessionAwareGraphQLSchema,
graphiql: true,
}),
),
); Then in your type definitions, you can access the ctx via the third "context" argument in your new GraphQLObjectType({
name: 'MyType',
fields: {
myField: {
type: GraphQLString,
resolve(parentValue, args, ctx) {
// use `ctx.session` here
},
},
},
}); Providing ExtensionsThe GraphQL response allows for adding additional information in a response to
a GraphQL query via a field in the response called When called, this is provided an argument which you can use to get information about the GraphQL request:
This example illustrates adding the amount of time consumed by running the provided query, which could perhaps be used by your development tools. const { graphqlHTTP } = require('koa-graphql');
const app = new Koa();
const extensions = ({
document,
variables,
operationName,
result,
context,
}) => {
return {
runTime: Date.now() - context.startTime,
};
};
app.use(
mount(
'/graphql',
graphqlHTTP((request) => {
return {
schema: MyGraphQLSchema,
context: { startTime: Date.now() },
graphiql: true,
extensions,
};
}),
),
); When querying this endpoint, it would include this information in the result, for example: {
"data": { ... },
"extensions": {
"runTime": 135
}
} Additional Validation RulesGraphQL's validation phase checks the query to ensure that it can be successfully executed against the schema. The A validation rule is a function which returns a visitor for one or more node Types. Below is an example of a validation preventing the specific field name import { GraphQLError } from 'graphql';
export function DisallowMetadataQueries(context) {
return {
Field(node) {
const fieldName = node.name.value;
if (fieldName === 'metadata') {
context.reportError(
new GraphQLError(
`Validation: Requesting the field ${fieldName} is not allowed`,
),
);
}
},
};
} Disabling IntrospectionDisabling introspection does not reflect best practices and does not necessarily make your
application any more secure. Nevertheless, disabling introspection is possible by utilizing the
import { NoSchemaIntrospectionCustomRule } from 'graphql';
app.use(
mount(
'/graphql',
graphqlHTTP((request) => {
return {
schema: MyGraphQLSchema,
validationRules: [NoSchemaIntrospectionCustomRule],
};
}),
),
); Custom GraphiQL ThemesTo use custom GraphiQL theme you should pass to router.all(
'/graphql',
graphqlHTTP({
schema: MyGraphQLSchema,
graphiql: {
editorTheme: 'blackboard',
},
}),
); List of available CodeMirror themes or an object with router.all(
'/graphql',
graphqlHTTP({
schema: MyGraphQLSchema,
graphiql: {
editorTheme: {
name: 'blackboard',
url: 'https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.53.2/theme/erlang-dark.css',
},
},
}),
); For details see the GraphiQL spec Additional Validation RulesGraphQL's validation phase checks the query to ensure that it can be successfully executed against the schema. The A validation rule is a function which returns a visitor for one or more node Types. Below is an example of a validation preventing the specific field name import { GraphQLError } from 'graphql';
export function DisallowMetadataQueries(context) {
return {
Field(node) {
const fieldName = node.name.value;
if (fieldName === 'metadata') {
context.reportError(
new GraphQLError(
`Validation: Requesting the field ${fieldName} is not allowed`,
),
);
}
},
};
} Debugging TipsDuring development, it's useful to get more information from errors, such as
stack traces. Providing a function to customFormatErrorFn: (error, ctx) => ({
message: error.message,
locations: error.locations,
stack: error.stack ? error.stack.split('\n') : [],
path: error.path,
}); ExamplesOther Relevant ProjectsPlease checkout awesome-graphql. |