Skip to content

Commit

Permalink
feat(@whook/example): add GraphQL server
Browse files Browse the repository at this point in the history
  • Loading branch information
nfroidure committed Mar 27, 2020
1 parent cac0452 commit 3f957d9
Show file tree
Hide file tree
Showing 13 changed files with 406 additions and 11 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/whook-example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@
"@whook/cors": "^3.1.3",
"@whook/http-router": "^3.1.3",
"@whook/swagger-ui": "^3.1.3",
"@whook/graphql": "^3.1.3",
"@whook/graphiql": "^3.1.3",
"@whook/whook": "^3.1.3",
"apollo-server-core": "^2.11.0",
"common-services": "^7.0.0",
"ecstatic": "^4.1.2",
"http-auth-utils": "^2.3.0",
Expand Down
3 changes: 3 additions & 0 deletions packages/whook-example/src/__snapshots__/cli.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ Object {
- printEnv: A command printing every env values
# Provided by \\"@whook/graphql\\": none
# Provided by \\"@whook/cli\\": 6 commands
- config: A simple program that returns the queryed config value
- create: A command helping to create new Whook files easily
Expand Down
145 changes: 144 additions & 1 deletion packages/whook-example/src/__snapshots__/index.test.ts.snap

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions packages/whook-example/src/config/common/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { WhookConfigs } from '@whook/whook';
import { AuthenticationConfig } from '../../services/authentication';
import { APIConfig } from '../../services/API';
import { DEFAULT_ERRORS_DESCRIPTORS } from '@whook/http-router';
import { WhookGraphQLConfig } from '@whook/graphql';
import { WhookGraphIQLConfig } from '@whook/graphiql';

const packageConf = require('../../../package');
const DEBUG_NODE_ENVS = ['test', 'development', 'staging'];
Expand All @@ -15,6 +17,8 @@ export type AppConfigs = WhookConfigs &
WhookAuthorizationConfig &
WhookSwaggerUIConfig &
CORSConfig &
WhookGraphQLConfig &
WhookGraphIQLConfig &
APIConfig;

const CONFIG: AppConfigs = {
Expand Down Expand Up @@ -53,6 +57,10 @@ const CONFIG: AppConfigs = {
].join(','),
Vary: 'Origin',
},
GRAPHIQL: {
path: '/graphiql',
defaultQuery: '{ hello }',
},
};

export default CONFIG;
1 change: 1 addition & 0 deletions packages/whook-example/src/config/development/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import COMMON_CONFIG, { AppConfigs } from '../common/config';

const CONFIG: AppConfigs = {
...COMMON_CONFIG,
DEV_ACCESS_MECHANISM: 'Fake',
DEV_ACCESS_TOKEN: 'admin|1|1',
DEFAULT_MECHANISM: 'Fake',
// This allows you to map service names depending on
Expand Down
21 changes: 21 additions & 0 deletions packages/whook-example/src/handlers/getGraphQL.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {
initGetGraphQL,
getGraphQLDefinition as baseDefinition,
} from '@whook/graphql';

// Add authentication to the base getGraphQL endpoints that
// would otherwise be public per default
export const definition = {
...baseDefinition,
operation: {
...baseDefinition.operation,

security: [
{
bearerAuth: ['admin'],
},
],
},
};

export default initGetGraphQL;
21 changes: 21 additions & 0 deletions packages/whook-example/src/handlers/postGraphQL.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {
initPostGraphQL,
postGraphQLDefinition as baseDefinition,
} from '@whook/graphql';

// Add authentication to the base postGraphQL endpoints that
// would otherwise be public per default
export const definition = {
...baseDefinition,
operation: {
...baseDefinition.operation,

security: [
{
bearerAuth: ['admin'],
},
],
},
};

export default initPostGraphQL;
31 changes: 29 additions & 2 deletions packages/whook-example/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import {
} from '@whook/whook';
import initHTTPRouter from '@whook/http-router';
import wrapHTTPRouterWithSwaggerUI from '@whook/swagger-ui';
import wrapHTTPRouterWithGraphIQL from '@whook/graphiql';
import { initGraphQL, WhookGraphQLFragmentService } from '@whook/graphql';
import { gql } from 'apollo-server-core';

// Per convention a Whook server main file must export
// the following 3 functions to be composable:
Expand All @@ -34,7 +37,9 @@ export async function prepareServer<S = Services>(
// Add here any logic bounded to the server only
// For example, here we add a Swagger UI page for
// development purpose
$.register(wrapHTTPRouterWithSwaggerUI(initHTTPRouter));
$.register(
wrapHTTPRouterWithGraphIQL(wrapHTTPRouterWithSwaggerUI(initHTTPRouter)),
);

return await prepareBaseServer(injectedNames, $);
}
Expand Down Expand Up @@ -70,7 +75,29 @@ export async function prepareEnvironment(
$.register(constant('TRANSACTIONS', {}));

// Setup your own whook plugins or avoid whook defaults by leaving it empty
$.register(constant('WHOOK_PLUGINS', ['@whook/cli', '@whook/whook']));
$.register(
constant('WHOOK_PLUGINS', ['@whook/graphql', '@whook/cli', '@whook/whook']),
);

// Declare the GraphQL schema fragments
const helloFragment: WhookGraphQLFragmentService = {
typeDefs: gql`
type Query {
hello: String
}
schema {
query: Query
}
`,
resolvers: {
Query: {
hello: () => 'Hello world!',
},
},
};

$.register(initGraphQL);
$.register(constant('graphQLFragments', [helloFragment]));

return $;
}
1 change: 1 addition & 0 deletions packages/whook-example/src/services/API.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { augmentAPIWithCORS } from '@whook/cors';
import { WhookConfig, WhookAPIDefinitions, noop } from '@whook/whook';
import { LogService } from 'common-services';
import { OpenAPIV3 } from 'openapi-types';
import { getGraphQLDefinition, postGraphQLDefinition } from '@whook/graphql';

export type APIEnv = {
DEV_MODE?: string;
Expand Down
164 changes: 164 additions & 0 deletions packages/whook-example/src/services/__snapshots__/API.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,21 @@ exports[`API should always have the same amount of basic authenticated endpoints
exports[`API should always have the same amount of bearer authenticated endpoints 1`] = `
Array [
"get /diag",
"get /graphql",
"get /openAPI",
"post /graphql",
]
`;

exports[`API should always have the same amount of endpoints 1`] = `
Array [
"get /delay",
"get /diag",
"get /graphql",
"get /openAPI",
"get /ping",
"get /time",
"post /graphql",
"put /echo",
]
`;
Expand All @@ -28,6 +32,7 @@ Array [
"options /delay",
"options /diag",
"options /echo",
"options /graphql",
"options /openAPI",
"options /ping",
"options /time",
Expand All @@ -45,9 +50,11 @@ exports[`API should always have the same amount of publicly documented endpoints
Array [
"get /delay",
"get /diag",
"get /graphql",
"get /openAPI",
"get /ping",
"get /time",
"post /graphql",
"put /echo",
]
`;
Expand Down Expand Up @@ -278,6 +285,163 @@ Object {
],
},
},
"/graphql": Object {
"get": Object {
"operationId": "getGraphQL",
"parameters": Array [
Object {
"description": "The GraphQL query",
"in": "query",
"name": "query",
"required": true,
"schema": Object {
"type": "string",
},
},
Object {
"description": "The GraphQL variables",
"in": "query",
"name": "variables",
"required": false,
"schema": Object {
"type": "string",
},
},
Object {
"description": "The GraphQL operation name",
"in": "query",
"name": "operationName",
"required": false,
"schema": Object {
"type": "string",
},
},
],
"responses": Object {
"200": Object {
"content": Object {
"application/json": Object {
"schema": Object {
"additionalProperties": true,
"type": "object",
},
},
},
"description": "Successfully ran the GraphQL query",
},
},
"security": Array [
Object {
"bearerAuth": Array [
"admin",
],
},
],
"summary": "Graphql endpoint",
"tags": Array [
"graphql",
],
},
"options": Object {
"operationId": "optionsWithCORS",
"parameters": Array [
Object {
"description": "The GraphQL query",
"in": "query",
"name": "query",
"required": false,
"schema": Object {
"type": "string",
},
},
Object {
"description": "The GraphQL variables",
"in": "query",
"name": "variables",
"required": false,
"schema": Object {
"type": "string",
},
},
Object {
"description": "The GraphQL operation name",
"in": "query",
"name": "operationName",
"required": false,
"schema": Object {
"type": "string",
},
},
Object {
"in": "query",
"name": "access_token",
"schema": Object {
"type": "string",
},
},
],
"responses": Object {
"200": Object {
"description": "CORS sent.",
},
},
"summary": "Enable OPTIONS for CORS",
"tags": Array [
"CORS",
],
"x-whook": Object {
"private": true,
"sourceOperationId": "getGraphQL",
"suffix": "CORS",
"type": "http",
},
},
"post": Object {
"operationId": "postGraphQL",
"parameters": Array [],
"requestBody": Object {
"content": Object {
"application/json": Object {
"schema": Object {
"additionalProperties": true,
"properties": Object {
"query": Object {
"type": "string",
},
},
"type": "object",
},
},
},
"description": "The GraphQL query",
"required": false,
},
"responses": Object {
"200": Object {
"content": Object {
"application/json": Object {
"schema": Object {
"additionalProperties": true,
"type": "object",
},
},
},
"description": "Successfully ran the GraphQL query",
},
},
"security": Array [
Object {
"bearerAuth": Array [
"admin",
],
},
],
"summary": "Graphql endpoint",
"tags": Array [
"graphql",
],
},
},
"/openAPI": Object {
"get": Object {
"operationId": "getOpenAPI",
Expand Down
5 changes: 4 additions & 1 deletion packages/whook-graphql/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,10 @@ describe('GraphQL server', () => {
);
$.register(
constant('GRAPHQL_SERVER_OPTIONS', {
context,
context: async ({ operation, requestContext }) => ({
operationId: operation.operationId,
authenticationData: requestContext.authenticationData,
}),
}),
);

Expand Down

0 comments on commit 3f957d9

Please sign in to comment.