Implement GraphQL server setup (#16)

* Set up gql server

* Get config data from environment file
This commit is contained in:
neerajvijay1997
2024-02-01 11:37:57 +05:30
committed by Ashwin Phatak
parent ea3addfd61
commit f287929e94
9 changed files with 645 additions and 33 deletions
+4
View File
@@ -0,0 +1,4 @@
[server]
host = "127.0.0.1"
port = 8000
gqlPath = "/graphql"
+8 -2
View File
@@ -4,22 +4,28 @@
"main": "index.js",
"license": "MIT",
"dependencies": {
"@types/debug": "^4.1.5",
"@types/express": "^4.17.21",
"@types/node": "^20.11.0",
"@types/debug": "^4.1.5",
"apollo-server-core": "^3.13.0",
"apollo-server-express": "^3.13.0",
"express": "^4.18.2",
"fs-extra": "^11.2.0",
"graphql": "^16.8.1",
"reflect-metadata": "^0.2.1",
"toml": "^3.0.0",
"ts-node": "^10.9.2",
"typeorm": "^0.3.19",
"typescript": "^5.3.3"
},
"scripts": {
"start": "DEBUG=snowball:* ts-node ./src/server.ts",
"start": "DEBUG=snowball:* ts-node ./src/index.ts",
"lint": "eslint .",
"format": "prettier --write .",
"format:check": "prettier --check ."
},
"devDependencies": {
"@types/fs-extra": "^11.0.4",
"@typescript-eslint/eslint-plugin": "^6.18.1",
"@typescript-eslint/parser": "^6.18.1",
"better-sqlite3": "^9.2.2",
+28
View File
@@ -0,0 +1,28 @@
import 'reflect-metadata';
import debug from 'debug';
import { initializeDatabase } from './database';
import { createAndStartServer } from './server';
import { createResolvers } from './resolver';
import { typeDefs } from './schema';
import { getConfig } from './utils';
import { Config } from './type';
const log = debug('snowball:server');
const configFilePath = 'environments/local.toml';
export const main = async (): Promise<void> => {
// TODO: get config path using cli
const { server } = await getConfig<Config>(configFilePath);
await initializeDatabase();
await createAndStartServer(typeDefs, createResolvers, server);
};
main()
.then(() => {
log('Starting server...');
})
.catch((err) => {
log(err);
});
+12
View File
@@ -0,0 +1,12 @@
const user = {
id: 2
};
export const createResolvers = async (): Promise<any> => {
return {
Query: {
// TODO: fetch user data from db
getUser: () => user
}
};
};
+9
View File
@@ -0,0 +1,9 @@
export const typeDefs = /* GraphQL */ `
type User {
id: Int
}
type Query {
getUser: User
}
`;
+47 -18
View File
@@ -1,30 +1,59 @@
import express, { Request, Response } from 'express';
import 'reflect-metadata';
import debug from 'debug';
import express from 'express';
import { ApolloServer } from 'apollo-server-express';
import { createServer } from 'http';
import {
ApolloServerPluginDrainHttpServer,
ApolloServerPluginLandingPageLocalDefault
} from 'apollo-server-core';
import { initializeDatabase } from './database';
import { TypeSource } from '@graphql-tools/utils';
import { makeExecutableSchema } from '@graphql-tools/schema';
import { ServerConfig } from './type';
const log = debug('snowball:server');
export const main = async (): Promise<void> => {
await initializeDatabase();
const DEFAULT_GQL_PATH = '/graphql';
export const createAndStartServer = async (
typeDefs: TypeSource,
resolvers: any,
serverConfig: ServerConfig
): Promise<ApolloServer> => {
const { host, port, gqlPath = DEFAULT_GQL_PATH } = serverConfig;
const app = express();
const port = 8080;
app.get('/', (req: Request, res: Response) => {
res.send('Hello, TypeScript Express Server!');
// Create HTTP server
const httpServer = createServer(app);
// Create the schema
const schema = makeExecutableSchema({
typeDefs,
resolvers: await resolvers()
});
app.listen(port, () => {
log(`Server is running at http://localhost:${port}`);
const server = new ApolloServer({
schema,
csrfPrevention: true,
plugins: [
// Proper shutdown for the HTTP server
ApolloServerPluginDrainHttpServer({ httpServer }),
ApolloServerPluginLandingPageLocalDefault({ embed: true })
]
});
await server.start();
server.applyMiddleware({
app,
path: gqlPath
});
httpServer.listen(port, host, () => {
log(`Server is listening on ${host}:${port}${server.graphqlPath}`);
});
return server;
};
main()
.then(() => {
log('Starting server...');
})
.catch((err) => {
log(err);
});
+9
View File
@@ -0,0 +1,9 @@
export interface ServerConfig {
host: string;
port: number;
gqlPath?: string;
}
export interface Config {
server: ServerConfig;
}
+21
View File
@@ -0,0 +1,21 @@
import fs from 'fs-extra';
import path from 'path';
import toml from 'toml';
import debug from 'debug';
const log = debug('snowball:utils');
export const getConfig = async <ConfigType>(
configFile: string
): Promise<ConfigType> => {
const configFilePath = path.resolve(configFile);
const fileExists = await fs.pathExists(configFilePath);
if (!fileExists) {
throw new Error(`Config file not found: ${configFilePath}`);
}
const config = toml.parse(await fs.readFile(configFilePath, 'utf8'));
log('config', JSON.stringify(config, null, 2));
return config;
};