diff --git a/packages/backend/package.json b/packages/backend/package.json index bc0f3937..a2fefade 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -12,6 +12,7 @@ "debug": "~2.6.9", "dotenv": "^10.0.0", "express": "~4.16.1", + "express-graphql": "^0.12.0", "http-errors": "~1.6.3", "morgan": "^1.10.0", "winston": "^3.3.3" diff --git a/packages/backend/src/app.ts b/packages/backend/src/app.ts index 19bbf4be..e67c7a9e 100644 --- a/packages/backend/src/app.ts +++ b/packages/backend/src/app.ts @@ -1,10 +1,12 @@ import appConfig from './config/app' import createError from 'http-errors'; import express, { Request, Response, NextFunction } from 'express'; +import { graphqlHTTP } from 'express-graphql'; import logger from './helpers/logger'; import morgan from './helpers/morgan'; -import indexRouter from './routes/index'; +import rootResolver from './graphql/root-resolver' +import graphQLSchema from './graphql/graphql-schema' const app = express(); const port = appConfig.port; @@ -13,7 +15,14 @@ app.use(morgan); app.use(express.json()); app.use(express.urlencoded({ extended: false })); -app.use('/', indexRouter); +app.use( + '/graphql', + graphqlHTTP({ + schema: graphQLSchema, + rootValue: rootResolver, + graphiql: true, + }), +); // catch 404 and forward to error handler app.use(function(req: Request, res: Response, next: NextFunction) { diff --git a/packages/backend/src/graphql/graphql-schema.ts b/packages/backend/src/graphql/graphql-schema.ts new file mode 100644 index 00000000..df5cbc68 --- /dev/null +++ b/packages/backend/src/graphql/graphql-schema.ts @@ -0,0 +1,9 @@ +import { buildSchema } from 'graphql'; + +const graphQLSchema = buildSchema(` + type Query { + hello: String + } +`); + +export default graphQLSchema; diff --git a/packages/backend/src/graphql/root-resolver.ts b/packages/backend/src/graphql/root-resolver.ts new file mode 100644 index 00000000..065bd91d --- /dev/null +++ b/packages/backend/src/graphql/root-resolver.ts @@ -0,0 +1,7 @@ +const rootResolver = { + hello: () => { + return 'Hello world!'; + }, +}; + +export default rootResolver; diff --git a/packages/backend/src/helpers/morgan.ts b/packages/backend/src/helpers/morgan.ts index 9a9ae920..65934f76 100644 --- a/packages/backend/src/helpers/morgan.ts +++ b/packages/backend/src/helpers/morgan.ts @@ -1,13 +1,19 @@ import morgan, { StreamOptions } from 'morgan'; - +import { Request } from 'express'; import logger from './logger'; const stream: StreamOptions = { - write: (message) => logger.http(message.substring(0, message.lastIndexOf('\n'))) + write: (message) => logger.http(message.substring(0, message.lastIndexOf("\n"))) }; +const registerGraphQLToken = () => { + morgan.token("graphql-query", (req: Request) => `GraphQL ${req.body.query}`); +}; + +registerGraphQLToken(); + const morganMiddleware = morgan( - ":method :url :status :res[content-length] - :response-time ms", + ":method :url :status :res[content-length] - :response-time ms\n:graphql-query", { stream } ); diff --git a/packages/backend/src/routes/index.ts b/packages/backend/src/routes/index.ts deleted file mode 100644 index 0ba08832..00000000 --- a/packages/backend/src/routes/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Request, Response } from 'express'; - -const indexRouter = (_request: Request, response: Response) => { - return response.json({ hello: 'world!' }) -}; - -export default indexRouter; diff --git a/yarn.lock b/yarn.lock index 8f1a8625..72ad4981 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3556,7 +3556,7 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: +accepts@^1.3.7, accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== @@ -5176,7 +5176,7 @@ content-disposition@0.5.3: dependencies: safe-buffer "5.1.2" -content-type@~1.0.4: +content-type@^1.0.4, content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== @@ -6793,6 +6793,16 @@ expect@^26.6.0, expect@^26.6.2: jest-message-util "^26.6.2" jest-regex-util "^26.0.0" +express-graphql@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/express-graphql/-/express-graphql-0.12.0.tgz#58deabc309909ca2c9fe2f83f5fbe94429aa23df" + integrity sha512-DwYaJQy0amdy3pgNtiTDuGGM2BLdj+YO2SgbKoLliCfuHv3VVTt7vNG/ZqK2hRYjtYHE2t2KB705EU94mE64zg== + dependencies: + accepts "^1.3.7" + content-type "^1.0.4" + http-errors "1.8.0" + raw-body "^2.4.1" + express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" @@ -7860,7 +7870,7 @@ http-errors@1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" -http-errors@~1.7.2: +http-errors@1.7.3, http-errors@~1.7.2: version "1.7.3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== @@ -7871,6 +7881,17 @@ http-errors@~1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" +http-errors@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.0.tgz#75d1bbe497e1044f51e4ee9e704a62f28d336507" + integrity sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + http-parser-js@>=0.5.1: version "0.5.3" resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9" @@ -12201,6 +12222,16 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" +raw-body@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" + integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== + dependencies: + bytes "3.1.0" + http-errors "1.7.3" + iconv-lite "0.4.24" + unpipe "1.0.0" + rc@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" @@ -13191,6 +13222,11 @@ setprototypeof@1.1.1: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + sha.js@^2.4.0, sha.js@^2.4.8: version "2.4.11" resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7"