Created
January 31, 2019 16:55
-
-
Save archilkarchava/64efb7b9cdbca301da43d807a33fbb38 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { ApolloServer, GraphQLOptions } from "apollo-server-express"; | |
| import { Request, Response } from "express"; | |
| import queryComplexity, { | |
| fieldConfigEstimator, | |
| simpleEstimator | |
| } from "graphql-query-complexity"; | |
| // hack to use graphql-query-complexity analysis | |
| export class ApolloServerWithQueryComplexity extends ApolloServer { | |
| public async createGraphQLServerOptions( | |
| req: Request, | |
| res: Response | |
| ): Promise<GraphQLOptions> { | |
| const options = await super.createGraphQLServerOptions(req, res); | |
| if (options.validationRules) { | |
| } | |
| return { | |
| ...options, | |
| validationRules: [ | |
| ...(options.validationRules ? options.validationRules : []), | |
| queryComplexity({ | |
| // The maximum allowed query complexity, queries above this threshold will be rejected | |
| maximumComplexity: 20, | |
| // The query variables. This is needed because the variables are not available | |
| // in the visitor of the graphql-js library | |
| variables: req.body.variables, | |
| // Optional callback function to retrieve the determined query complexity | |
| // Will be invoked weather the query is rejected or not | |
| // This can be used for logging or to implement rate limiting | |
| onComplete: (complexity: number) => { | |
| console.log("Query Complexity:", complexity); | |
| }, | |
| estimators: [ | |
| // Using fieldConfigEstimator is mandatory to make it work with type-graphql | |
| fieldConfigEstimator(), | |
| // This will assign each field a complexity of 1 if no other estimator | |
| // returned a value. We can define the default value for field not explicitly annotated | |
| simpleEstimator({ | |
| defaultComplexity: 1 | |
| }) | |
| ] | |
| }) as any | |
| ] | |
| }; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import * as connectRedis from "connect-redis"; | |
| import * as cors from "cors"; | |
| import * as dotenv from "dotenv"; | |
| import * as Express from "express"; | |
| import * as session from "express-session"; | |
| import { GraphQLSchema } from "graphql"; | |
| import "reflect-metadata"; | |
| import { formatArgumentValidationError } from "type-graphql"; | |
| import { createConnection } from "typeorm"; | |
| import { ApolloServerWithQueryComplexity } from "./ApolloServerWithQueryComplexity"; | |
| import { redis } from "./redis"; | |
| import { IMyContext } from "./types/MyContext"; | |
| import { createSchema } from "./utils/createSchema"; | |
| dotenv.config(); | |
| const main = async () => { | |
| try { | |
| await createConnection(); | |
| } catch (err) { | |
| throw new Error(err); | |
| } | |
| let schema: GraphQLSchema; | |
| try { | |
| schema = await createSchema(); | |
| } catch (err) { | |
| throw new Error(err); | |
| } | |
| const apolloServer = new ApolloServerWithQueryComplexity({ | |
| schema, | |
| formatError: formatArgumentValidationError, | |
| context: ({ req, res }: IMyContext) => ({ req, res }) | |
| }); | |
| const app = Express(); | |
| const RedisStore = connectRedis(session); | |
| app.use( | |
| cors({ | |
| credentials: true, | |
| origin: "http://localhost:3000" | |
| }) | |
| ); | |
| app.use( | |
| session({ | |
| store: new RedisStore({ | |
| client: redis as any | |
| }), | |
| name: "qid", | |
| secret: process.env.SESSION_SECRET!, | |
| resave: false, | |
| saveUninitialized: false, | |
| cookie: { | |
| httpOnly: true, | |
| secure: process.env.NODE_ENV === "production", | |
| maxAge: 1000 * 60 * 60 * 24 * 7 * 365 // 7 years | |
| } | |
| }) | |
| ); | |
| apolloServer.applyMiddleware({ app, cors: false }); | |
| app.listen(4000, () => { | |
| console.log("Server started on http://localhost:4000/graphql"); | |
| }); | |
| }; | |
| main().catch(err => { | |
| console.error(err); | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment