Skip to content

Commit

Permalink
feat(handler): Expose parseRequestParams from the core and each of …
Browse files Browse the repository at this point in the history
…the adapters (#111)
  • Loading branch information
enisdenjo authored Aug 28, 2023
1 parent 5d5a821 commit 2caae00
Show file tree
Hide file tree
Showing 16 changed files with 1,225 additions and 211 deletions.
41 changes: 39 additions & 2 deletions docs/modules/handler.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
### Functions

- [createHandler](handler.md#createhandler)
- [parseRequestParams](handler.md#parserequestparams-1)

## Server

Expand Down Expand Up @@ -124,8 +125,10 @@ ___

▸ (`req`): `Promise`<[`RequestParams`](../interfaces/common.RequestParams.md) \| [`Response`](handler.md#response) \| `void`\> \| [`RequestParams`](../interfaces/common.RequestParams.md) \| [`Response`](handler.md#response) \| `void`

The request parser for an incoming GraphQL request. It parses and validates the
request itself, including the request method and the content-type of the body.
The request parser for an incoming GraphQL request in the handler.

It should parse and validate the request itself, including the request method
and the content-type of the body.

In case you are extending the server to handle more request types, this is the
perfect place to do so.
Expand Down Expand Up @@ -258,3 +261,37 @@ console.log('Listening to port 4000');
#### Returns

[`Handler`](handler.md#handler)<`RequestRaw`, `RequestContext`\>

___

### parseRequestParams

**parseRequestParams**<`RequestRaw`, `RequestContext`\>(`req`): `Promise`<[`Response`](handler.md#response) \| [`RequestParams`](../interfaces/common.RequestParams.md)\>

The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.
It parses and validates the request itself, including the request method and the
content-type of the body.

If the HTTP request itself is invalid or malformed, the function will return an
appropriate [Response](handler.md#response).

If the HTTP request is valid, but is not a well-formatted GraphQL request, the
function will throw an error and it is up to the user to handle and respond as
they see fit.

#### Type parameters

| Name | Type |
| :------ | :------ |
| `RequestRaw` | `unknown` |
| `RequestContext` | `unknown` |

#### Parameters

| Name | Type |
| :------ | :------ |
| `req` | [`Request`](../interfaces/handler.Request.md)<`RequestRaw`, `RequestContext`\> |

#### Returns

`Promise`<[`Response`](handler.md#response) \| [`RequestParams`](../interfaces/common.RequestParams.md)\>
54 changes: 54 additions & 0 deletions docs/modules/use_express.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
### Functions

- [createHandler](use_express.md#createhandler)
- [parseRequestParams](use_express.md#parserequestparams)

## Server/express

Expand Down Expand Up @@ -66,3 +67,56 @@ console.log('Listening to port 4000');
#### Returns

`Handler`

___

### parseRequestParams

**parseRequestParams**(`req`, `res`): `Promise`<[`RequestParams`](../interfaces/common.RequestParams.md) \| ``null``\>

The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.

If the HTTP request _is not_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), the function will respond
on the `Response` argument and return `null`.

If the HTTP request _is_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), but is invalid or malformed,
the function will throw an error and it is up to the user to handle and respond as they see fit.

```js
import express from 'express'; // yarn add express
import { parseRequestParams } from 'graphql-http/lib/use/express';

const app = express();
app.all('/graphql', async (req, res) => {
try {
const maybeParams = await parseRequestParams(req, res);
if (!maybeParams) {
// not a well-formatted GraphQL over HTTP request,
// parser responded and there's nothing else to do
return;
}

// well-formatted GraphQL over HTTP request,
// with valid parameters
res.writeHead(200).end(JSON.stringify(maybeParams, null, ' '));
} catch (err) {
// well-formatted GraphQL over HTTP request,
// but with invalid parameters
res.writeHead(400).end(err.message);
}
});

app.listen({ port: 4000 });
console.log('Listening to port 4000');
```

#### Parameters

| Name | Type |
| :------ | :------ |
| `req` | `Request`<`ParamsDictionary`, `any`, `any`, `ParsedQs`, `Record`<`string`, `any`\>\> |
| `res` | `Response`<`any`, `Record`<`string`, `any`\>\> |

#### Returns

`Promise`<[`RequestParams`](../interfaces/common.RequestParams.md) \| ``null``\>
54 changes: 54 additions & 0 deletions docs/modules/use_fastify.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
### Functions

- [createHandler](use_fastify.md#createhandler)
- [parseRequestParams](use_fastify.md#parserequestparams)

## Server/fastify

Expand Down Expand Up @@ -66,3 +67,56 @@ console.log('Listening to port 4000');
#### Returns

`RouteHandler`

___

### parseRequestParams

**parseRequestParams**(`req`, `reply`): `Promise`<[`RequestParams`](../interfaces/common.RequestParams.md) \| ``null``\>

The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.

If the HTTP request _is not_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), the function will respond
on the `FastifyReply` argument and return `null`.

If the HTTP request _is_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), but is invalid or malformed,
the function will throw an error and it is up to the user to handle and respond as they see fit.

```js
import Fastify from 'fastify'; // yarn add fastify
import { parseRequestParams } from 'graphql-http/lib/use/fastify';

const fastify = Fastify();
fastify.all('/graphql', async (req, reply) => {
try {
const maybeParams = await parseRequestParams(req, reply);
if (!maybeParams) {
// not a well-formatted GraphQL over HTTP request,
// parser responded and there's nothing else to do
return;
}

// well-formatted GraphQL over HTTP request,
// with valid parameters
reply.status(200).send(JSON.stringify(maybeParams, null, ' '));
} catch (err) {
// well-formatted GraphQL over HTTP request,
// but with invalid parameters
reply.status(400).send(err.message);
}
});

fastify.listen({ port: 4000 });
console.log('Listening to port 4000');
```

#### Parameters

| Name | Type |
| :------ | :------ |
| `req` | `FastifyRequest`<`RouteGenericInterface`, `RawServerDefault`, `IncomingMessage`, `FastifySchema`, `FastifyTypeProviderDefault`, `unknown`, `FastifyBaseLogger`, `ResolveFastifyRequestType`<`FastifyTypeProviderDefault`, `FastifySchema`, `RouteGenericInterface`\>\> |
| `reply` | `FastifyReply`<`RawServerDefault`, `IncomingMessage`, `ServerResponse`<`IncomingMessage`\>, `RouteGenericInterface`, `unknown`, `FastifySchema`, `FastifyTypeProviderDefault`, `unknown`\> |

#### Returns

`Promise`<[`RequestParams`](../interfaces/common.RequestParams.md) \| ``null``\>
63 changes: 63 additions & 0 deletions docs/modules/use_fetch.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
### Functions

- [createHandler](use_fetch.md#createhandler)
- [parseRequestParams](use_fetch.md#parserequestparams)

## Server/fetch

Expand Down Expand Up @@ -87,3 +88,65 @@ console.log('Listening to port 4000');
##### Returns

`Promise`<`Response`\>

___

### parseRequestParams

**parseRequestParams**(`req`, `api?`): `Promise`<[`RequestParams`](../interfaces/common.RequestParams.md) \| `Response`\>

The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.

It is important to pass in the `abortedRef` so that the parser does not perform any
operations on a disposed request (see example).

If the HTTP request _is not_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), the function will return a `Response`.

If the HTTP request _is_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), but is invalid or malformed,
the function will throw an error and it is up to the user to handle and respond as they see fit.

```js
import http from 'http';
import { createServerAdapter } from '@whatwg-node/server'; // yarn add @whatwg-node/server
import { parseRequestParams } from 'graphql-http/lib/use/fetch';

// Use this adapter in _any_ environment.
const adapter = createServerAdapter({
handleRequest: async (req) => {
try {
const paramsOrResponse = await parseRequestParams(req);
if (paramsOrResponse instanceof Response) {
// not a well-formatted GraphQL over HTTP request,
// parser created a response object to use
return paramsOrResponse;
}

// well-formatted GraphQL over HTTP request,
// with valid parameters
return new Response(JSON.stringify(paramsOrResponse, null, ' '), {
status: 200,
});
} catch (err) {
// well-formatted GraphQL over HTTP request,
// but with invalid parameters
return new Response(err.message, { status: 400 });
}
},
});

const server = http.createServer(adapter);

server.listen(4000);
console.log('Listening to port 4000');
```

#### Parameters

| Name | Type |
| :------ | :------ |
| `req` | `Request` |
| `api` | `Partial`<[`FetchAPI`](../interfaces/use_fetch.FetchAPI.md)\> |

#### Returns

`Promise`<[`RequestParams`](../interfaces/common.RequestParams.md) \| `Response`\>
57 changes: 57 additions & 0 deletions docs/modules/use_http.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
### Functions

- [createHandler](use_http.md#createhandler)
- [parseRequestParams](use_http.md#parserequestparams)

## Server/http

Expand Down Expand Up @@ -78,3 +79,59 @@ console.log('Listening to port 4000');
##### Returns

`Promise`<`void`\>

___

### parseRequestParams

**parseRequestParams**(`req`, `res`): `Promise`<[`RequestParams`](../interfaces/common.RequestParams.md) \| ``null``\>

The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.

If the HTTP request _is not_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), the function will respond
on the `ServerResponse` argument and return `null`.

If the HTTP request _is_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), but is invalid or malformed,
the function will throw an error and it is up to the user to handle and respond as they see fit.

```js
import http from 'http';
import { parseRequestParams } from 'graphql-http/lib/use/http';

const server = http.createServer(async (req, res) => {
if (req.url.startsWith('/graphql')) {
try {
const maybeParams = await parseRequestParams(req, res);
if (!maybeParams) {
// not a well-formatted GraphQL over HTTP request,
// parser responded and there's nothing else to do
return;
}

// well-formatted GraphQL over HTTP request,
// with valid parameters
res.writeHead(200).end(JSON.stringify(maybeParams, null, ' '));
} catch (err) {
// well-formatted GraphQL over HTTP request,
// but with invalid parameters
res.writeHead(400).end(err.message);
}
} else {
res.writeHead(404).end();
}
});

server.listen(4000);
console.log('Listening to port 4000');
```

#### Parameters

| Name | Type |
| :------ | :------ |
| `req` | `IncomingMessage` |
| `res` | `ServerResponse`<`IncomingMessage`\> |

#### Returns

`Promise`<[`RequestParams`](../interfaces/common.RequestParams.md) \| ``null``\>
Loading

0 comments on commit 2caae00

Please sign in to comment.