Skip to content

Commit

Permalink
feat(connection): bring your own DB connection
Browse files Browse the repository at this point in the history
  • Loading branch information
goldcaddy77 committed May 28, 2021
1 parent b2bcabb commit 5d1c8e3
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 22 deletions.
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,15 +287,16 @@ When you start your server, there will be a new `generated` folder that Warthog

Most of the config in Warthog is done via environment variables (see `Config - Environment Variables` below). However, more complex/dynamic objects should be passed via the server config.

| attribute | description | default |
| ------------------------- | --------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
| container | TypeDI container. Warthog uses dependency injection under the hood. | empty container |
| authChecker | An instance of an [AuthChecker](https://typegraphql.ml/docs/authorization.html) to secure your resolvers. | |
| context | Context getter of form `(request: Request) => Promise<object>` | empty |
| logger | Logger | [debug](https://github.com/visionmedia/debug) |
| middlewares | [TypeGraphQL](https://typegraphql.ml/docs/middlewares.html) middlewares to add to your server | none |
| onBeforeGraphQLMiddleware | Callback executed just before the Graphql server is started. The Express app is passed. | none |
| onAfterGraphQLMiddleware | Callback executed just after the Graphql server is started. The Express app is passed. | none |
| attribute | description | default |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
| container | TypeDI container. Warthog uses dependency injection under the hood. | empty container |
| authChecker | An instance of an [AuthChecker](https://typegraphql.ml/docs/authorization.html) to secure your resolvers. | |
| connectionGetter | Connection getter of form `(config: Config) => Connection or Promise<Connection>`, asks for getter instead of raw connection in case we build in connection retries should a connection go down | none |
| context | Context getter of form `(request: Request) => Promise<object>` | empty |
| logger | Logger | [debug](https://github.com/visionmedia/debug) |
| middlewares | [TypeGraphQL](https://typegraphql.ml/docs/middlewares.html) middlewares to add to your server | none |
| onBeforeGraphQLMiddleware | Callback executed just before the Graphql server is started. The Express app is passed. | none |
| onAfterGraphQLMiddleware | Callback executed just after the Graphql server is started. The Express app is passed. | none |

## Config - Environment Variables

Expand Down
20 changes: 18 additions & 2 deletions src/core/server.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Server, ServerOptions } from './server';
import { setTestServerEnvironmentVariables } from '../test/server-vars';
import { getTestServer } from '../test/test-server';
import { createDBConnection } from '../torm';
import { Server, ServerOptions } from './server';

import express = require('express');
import { setTestServerEnvironmentVariables } from '../test/server-vars';

describe('Server', () => {
let server: Server<any>;
Expand Down Expand Up @@ -44,6 +45,21 @@ describe('Server', () => {
expect(appListenSpy).toHaveBeenCalledTimes(1);
expect(hasGraphQlRoute(server.expressApp._router)).toBeTruthy();
});

test('start a server with a custom DB connection', async () => {
const testConnectionName = 'custom-test-connection';
const connection = await createDBConnection({ name: testConnectionName });

const connectionGetter = () => {
return Promise.resolve(connection);
};

server = buildServer({ connectionGetter });
await server.start();

expect(server.getConnection().name).toEqual(testConnectionName);
expect(server.getConnection()).toEqual(connection);
});
});

function buildServer(options: ServerOptions<any>): Server<any> {
Expand Down
28 changes: 17 additions & 11 deletions src/core/server.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
// TODO-MVP: Add custom scalars such as graphql-iso-date
// import { GraphQLDate, GraphQLDateTime, GraphQLTime } from 'graphql-iso-date';

import { ApolloServer, OptionsJson, ApolloServerExpressConfig } from 'apollo-server-express';
import { PubSubEngine, PubSubOptions } from 'graphql-subscriptions';
import { ApolloServer, ApolloServerExpressConfig, OptionsJson } from 'apollo-server-express';
import * as Debug from 'debug';
import { Request } from 'express';
import express = require('express');
import { GraphQLID, GraphQLSchema } from 'graphql';
import { Binding } from 'graphql-binding';
import { DateResolver } from 'graphql-scalars';
import { PubSubEngine, PubSubOptions } from 'graphql-subscriptions';
import { Server as HttpServer } from 'http';
import { Server as HttpsServer } from 'https';
const open = require('open'); // eslint-disable-line @typescript-eslint/no-var-requires
import { AuthChecker, buildSchema } from 'type-graphql'; // formatArgumentValidationError
import { Container } from 'typedi';
import { Connection, ConnectionOptions, useContainer as TypeORMUseContainer } from 'typeorm';

import { logger, Logger } from '../core/logger';
import { getRemoteBinding } from '../gql';
import { DataLoaderMiddleware, healthCheckMiddleware } from '../middleware';
import { createDBConnection } from '../torm';

import { CodeGenerator } from './code-generator';
import { Config } from './config';

import { BaseContext } from './Context';

import * as Debug from 'debug';
import express = require('express');
const open = require('open'); // eslint-disable-line @typescript-eslint/no-var-requires

const debug = Debug('warthog:server');

Expand All @@ -34,6 +31,7 @@ export interface ServerOptions<T> {
apolloConfig?: ApolloServerExpressConfig;
authChecker?: AuthChecker<T>;
autoGenerateFiles?: boolean;
connectionGetter?: (config: Config) => Connection | Promise<Connection>;
context?: (request: Request) => object;
expressApp?: express.Application;
host?: string;
Expand Down Expand Up @@ -124,10 +122,14 @@ export class Server<C extends BaseContext> {
}

async establishDBConnection(): Promise<Connection> {
if (!this.connection) {
debug('establishDBConnection:start');
if (this.connection) {
return this.connection;
}

if (this.appOptions.connectionGetter) {
this.connection = await this.appOptions.connectionGetter(this.config);
} else {
this.connection = await createDBConnection(this.dbOptions);
debug('establishDBConnection:end');
}

return this.connection;
Expand All @@ -143,6 +145,10 @@ export class Server<C extends BaseContext> {
return `${this.getServerUrl()}/graphql`;
}

getConnection(): Connection {
return this.connection;
}

async getBinding(options: { origin?: string; token?: string } = {}): Promise<Binding> {
let binding;
try {
Expand Down

0 comments on commit 5d1c8e3

Please sign in to comment.