Skip to content

Commit

Permalink
feat(use/express,use/fastify,use/koa): Request context with the response
Browse files Browse the repository at this point in the history
Closes #66
  • Loading branch information
enisdenjo committed Mar 28, 2023
1 parent f519a97 commit 665175e
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 12 deletions.
19 changes: 19 additions & 0 deletions docs/interfaces/use_express.RequestContext.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[graphql-http](../README.md) / [use/express](../modules/use_express.md) / RequestContext

# Interface: RequestContext

[use/express](../modules/use_express.md).RequestContext

The context in the request for the handler.

## Table of contents

### Properties

- [res](use_express.RequestContext.md#res)

## Properties

### res

**res**: `Response`<`any`, `Record`<`string`, `any`\>\>
19 changes: 19 additions & 0 deletions docs/interfaces/use_fastify.RequestContext.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[graphql-http](../README.md) / [use/fastify](../modules/use_fastify.md) / RequestContext

# Interface: RequestContext

[use/fastify](../modules/use_fastify.md).RequestContext

The context in the request for the handler.

## Table of contents

### Properties

- [reply](use_fastify.RequestContext.md#reply)

## Properties

### reply

**reply**: `FastifyReply`<`RawServerDefault`, `IncomingMessage`, `ServerResponse`<`IncomingMessage`\>, `RouteGenericInterface`, `unknown`, `FastifySchema`, `FastifyTypeProviderDefault`, `unknown`\>
19 changes: 19 additions & 0 deletions docs/interfaces/use_koa.RequestContext.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[graphql-http](../README.md) / [use/koa](../modules/use_koa.md) / RequestContext

# Interface: RequestContext

[use/koa](../modules/use_koa.md).RequestContext

The context in the request for the handler.

## Table of contents

### Properties

- [res](use_koa.RequestContext.md#res)

## Properties

### res

**res**: `Response`
6 changes: 5 additions & 1 deletion docs/modules/use_express.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

## Table of contents

### Interfaces

- [RequestContext](../interfaces/use_express.RequestContext.md)

### Type Aliases

- [HandlerOptions](use_express.md#handleroptions)
Expand All @@ -16,7 +20,7 @@

### HandlerOptions

Ƭ **HandlerOptions**<`Context`\>: [`HandlerOptions`](../interfaces/handler.HandlerOptions.md)<`Request`, `undefined`, `Context`\>
Ƭ **HandlerOptions**<`Context`\>: [`HandlerOptions`](../interfaces/handler.HandlerOptions.md)<`Request`, [`RequestContext`](../interfaces/use_express.RequestContext.md), `Context`\>

Handler options when using the express adapter.

Expand Down
6 changes: 5 additions & 1 deletion docs/modules/use_fastify.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

## Table of contents

### Interfaces

- [RequestContext](../interfaces/use_fastify.RequestContext.md)

### Type Aliases

- [HandlerOptions](use_fastify.md#handleroptions)
Expand All @@ -16,7 +20,7 @@

### HandlerOptions

Ƭ **HandlerOptions**<`Context`\>: [`HandlerOptions`](../interfaces/handler.HandlerOptions.md)<`FastifyRequest`, `undefined`, `Context`\>
Ƭ **HandlerOptions**<`Context`\>: [`HandlerOptions`](../interfaces/handler.HandlerOptions.md)<`FastifyRequest`, [`RequestContext`](../interfaces/use_fastify.RequestContext.md), `Context`\>

Handler options when using the fastify adapter.

Expand Down
6 changes: 5 additions & 1 deletion docs/modules/use_koa.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

## Table of contents

### Interfaces

- [RequestContext](../interfaces/use_koa.RequestContext.md)

### Type Aliases

- [HandlerOptions](use_koa.md#handleroptions)
Expand All @@ -16,7 +20,7 @@

### HandlerOptions

Ƭ **HandlerOptions**<`Context`\>: [`HandlerOptions`](../interfaces/handler.HandlerOptions.md)<`IncomingMessage`, `undefined`, `Context`\>
Ƭ **HandlerOptions**<`Context`\>: [`HandlerOptions`](../interfaces/handler.HandlerOptions.md)<`IncomingMessage`, [`RequestContext`](../interfaces/use_koa.RequestContext.md), `Context`\>

Handler options when using the koa adapter.

Expand Down
81 changes: 81 additions & 0 deletions src/__tests__/use.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,31 @@ describe('express', () => {
}
});
}

it('should allow manipulating the response from the request context', async () => {
const app = express();
app.all(
'/',
createExpressHandler({
schema,
context(req) {
req.context.res.setHeader('x-test', 'test-x');
return undefined;
},
}),
);

const [url, dispose] = startDisposableServer(app.listen(0));

const res = await fetch(url + '?query={hello}');

await expect(res.text()).resolves.toMatchInlineSnapshot(
`"{"data":{"hello":"world"}}"`,
);
expect(res.headers.get('x-test')).toBe('test-x');

await dispose();
});
});

describe('fastify', () => {
Expand Down Expand Up @@ -104,6 +129,35 @@ describe('fastify', () => {
}
});
}

it('should allow manipulating the response from the request context', async () => {
const app = fastify();

app.all(
'/',
createFastifyHandler({
schema,
context(req) {
req.context.reply.header('x-test', 'test-x');
return undefined;
},
}),
);

// call ready since we're not calling listen
app.ready();

const [url, dispose] = startDisposableServer(app.server);

const res = await fetch(url + '?query={hello}');

await expect(res.text()).resolves.toMatchInlineSnapshot(
`"{"data":{"hello":"world"}}"`,
);
expect(res.headers.get('x-test')).toBe('test-x');

await dispose();
});
});

describe('fetch', () => {
Expand Down Expand Up @@ -137,4 +191,31 @@ describe('koa', () => {
}
});
}

it('should allow manipulating the response from the request context', async () => {
const app = new Koa();
app.use(
mount(
'/',
createKoaHandler({
schema,
context(req) {
req.context.res.set('x-test', 'test-x');
return undefined;
},
}),
),
);

const [url, dispose] = startDisposableServer(app.listen(0));

const res = await fetch(url + '?query={hello}');

await expect(res.text()).resolves.toMatchInlineSnapshot(
`"{"data":{"hello":"world"}}"`,
);
expect(res.headers.get('x-test')).toBe('test-x');

await dispose();
});
});
15 changes: 12 additions & 3 deletions src/use/express.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
import type { Request, Handler } from 'express';
import type { Request, Response, Handler } from 'express';
import {
createHandler as createRawHandler,
HandlerOptions as RawHandlerOptions,
OperationContext,
} from '../handler';

/**
* The context in the request for the handler.
*
* @category Server/express
*/
export interface RequestContext {
res: Response;
}

/**
* Handler options when using the express adapter.
*
* @category Server/express
*/
export type HandlerOptions<Context extends OperationContext = undefined> =
RawHandlerOptions<Request, undefined, Context>;
RawHandlerOptions<Request, RequestContext, Context>;

/**
* Create a GraphQL over HTTP spec compliant request handler for
Expand Down Expand Up @@ -54,7 +63,7 @@ export function createHandler<Context extends OperationContext = undefined>(
});
},
raw: req,
context: undefined,
context: { res },
});
res.writeHead(init.status, init.statusText, init.headers).end(body);
} catch (err) {
Expand Down
15 changes: 12 additions & 3 deletions src/use/fastify.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
import type { FastifyRequest, RouteHandler } from 'fastify';
import type { FastifyRequest, FastifyReply, RouteHandler } from 'fastify';
import {
createHandler as createRawHandler,
HandlerOptions as RawHandlerOptions,
OperationContext,
} from '../handler';

/**
* The context in the request for the handler.
*
* @category Server/fastify
*/
export interface RequestContext {
reply: FastifyReply;
}

/**
* Handler options when using the fastify adapter.
*
* @category Server/fastify
*/
export type HandlerOptions<Context extends OperationContext = undefined> =
RawHandlerOptions<FastifyRequest, undefined, Context>;
RawHandlerOptions<FastifyRequest, RequestContext, Context>;

/**
* Create a GraphQL over HTTP spec compliant request handler for
Expand Down Expand Up @@ -45,7 +54,7 @@ export function createHandler<Context extends OperationContext = undefined>(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
body: req.body as any,
raw: req,
context: undefined,
context: { reply },
});
reply
.status(init.status)
Expand Down
15 changes: 12 additions & 3 deletions src/use/koa.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
import type { Middleware } from 'koa';
import type { Middleware, Response } from 'koa';
import type { IncomingMessage } from 'http';
import {
createHandler as createRawHandler,
HandlerOptions as RawHandlerOptions,
OperationContext,
} from '../handler';

/**
* The context in the request for the handler.
*
* @category Server/koa
*/
export interface RequestContext {
res: Response;
}

/**
* Handler options when using the koa adapter.
*
* @category Server/koa
*/
export type HandlerOptions<Context extends OperationContext = undefined> =
RawHandlerOptions<IncomingMessage, undefined, Context>;
RawHandlerOptions<IncomingMessage, RequestContext, Context>;

/**
* Create a GraphQL over HTTP spec compliant request handler for
Expand Down Expand Up @@ -56,7 +65,7 @@ export function createHandler<Context extends OperationContext = undefined>(
});
},
raw: ctx.req,
context: undefined,
context: { res: ctx.response },
});
ctx.body = body;
ctx.response.status = init.status;
Expand Down

0 comments on commit 665175e

Please sign in to comment.