docs: add explanation for Edge/Serverless bundling of transports (#5638)

This commit is contained in:
Valentin Cocaud 2024-10-08 13:00:47 +02:00 committed by GitHub
parent 3d5829b753
commit 925b41bfd7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 173 additions and 34 deletions

View file

@ -10,17 +10,32 @@ the AWS cloud. Hive Gateway is platform agnostic so they can fit together easily
Edge](/docs/gateway/deployment/serverless) page.
</Callout>
```ts
import { APIGatewayEvent, APIGatewayProxyResult, Context } from 'aws-lambda'
import { createGatewayRuntime } from '@graphql-hive/gateway'
See [Bundling Problems](/docs/gateway/deployment/serverless#bundling-problem) for more details about
how to load the supergraph and `transports` option.
const serveRuntime = createGatewayRuntime(/* Your configuration */)
```js filename="gateway.ts"
import { createGatewayRuntime } from '@graphql-hive/gateway'
import http from '@graphql-mesh/transport-http'
import supergraph from './supergraph.js'
export const gateway = createGatewayRuntime({
// All options available in `gateway.config.ts` configuration can also be passed here.
supergraph,
transports: {
http // For example, http transport is required for subgraphs using standard GraphQL over HTTP.
}
})
```
```ts filename="index.ts"
import { APIGatewayEvent, APIGatewayProxyResult, Context } from 'aws-lambda'
import { gateway } from './gateway'
export async function handler(
event: APIGatewayEvent,
lambdaContext: Context
): Promise<APIGatewayProxyResult> {
const response = await serveRuntime.fetch(
const response = await gateway.fetch(
event.path +
'?' +
new URLSearchParams((event.queryStringParameters as Record<string, string>) || {}).toString(),

View file

@ -10,14 +10,25 @@ agnostic and can be deployed to Azure Functions as well.
Edge](/docs/gateway/deployment/serverless) page.
</Callout>
See [Bundling Problems](/docs/gateway/deployment/serverless#bundling-problem) for more details about
how to load the supergraph and `transports` option.
```ts
import { app } from '@azure/functions'
import { createGatewayRuntime } from '@graphql-hive/gateway'
import http from '@graphql-mesh/transport-http'
import supergraph from './supergraph'
const handler = createGatewayRuntime(/* Your configuration */)
export const gateway = createGatewayRuntime({
// All options available in `gateway.config.ts` configuration can also be passed here.
supergraph,
transports: {
http // For example, http transport is required for subgraphs using standard GraphQL over HTTP.
}
})
app.http('graphql', {
method: ['GET', 'POST'],
handler
gateway
})
```

View file

@ -14,14 +14,29 @@ configuring or maintaining infrastructure.
Edge](/docs/gateway/deployment/serverless) page.
</Callout>
```ts
import { createGatewayRuntime } from '@graphql-hive/gateway'
See [Bundling Problems](/docs/gateway/deployment/serverless#bundling-problem) for more details about
how to load the supergraph and `transports` option.
const gatewayRuntime = createGatewayRuntime({
// gatewayConfig
```ts filename="index.js"
import { createGatewayRuntime } from '@graphql-hive/gateway'
import http from '@graphql-mesh/transport-http'
import supergraph from './supergraph'
export const gateway = createGatewayRuntime({
// All options available in `gateway.config.ts` configuration can also be passed here.
supergraph,
transports: {
http // For example, http transport is required for subgraphs using standard GraphQL over HTTP.
}
})
export default { fetch: gatewayRuntime }
export default { fetch: gateway }
```
```js filename="supergraph.js"
export default /* GraphQL */ `
PLACE YOUR SUPERGRAPH SDL HERE
`
```
<Callout>

View file

@ -58,10 +58,26 @@ npm i @google-cloud/functions-framework @graphql-hive/gateway graphql
### Usage
#### Gateway runtime
You can create a runnable `index.js` script that will be executed by Google Cloud Run Function to
serve requests.
See [Bundling Problems](/docs/gateway/deployment/serverless#bundling-problem) for more details about
how to load the supergraph and `transports` option.
```js filename=index.js
import { createGatewayRuntime } from '@graphql-hive/gateway'
import http from '@graphql-mesh/transport-http'
import supergraph from './supergraph.js'
export const graphql = createGatewayRuntime(/* Configuration */)
export const graphql = createGatewayRuntime({
// All options available in `gateway.config.ts` configuration can also be passed here.
supergraph,
transports: {
http // For example, http transport is required for subgraphs using standard GraphQL over HTTP.
}
})
```
You can now deploy your function with `gcloud` CLI:

View file

@ -8,9 +8,29 @@ serverless environment like AWS Lambda, Cloudflare Workers, or Azure Functions.
For Serverless environments, you cannot use Gateway CLI `hive-gateway` but you can use the
`createGatewayRuntime` function from `@graphql-hive/gateway` package.
<Callout>
Please read carefully following sections, most importantly [Bundling
Problems](#bundling-problems). Serverless and Edge are very specific environment that are comming
with very specific requirements.
</Callout>
## Configuration
The gateway configuration goes into `createGatewayRuntime` function instead of `gatewayConfig`
export in `gateway.config.ts` file.
See
[Gateway Configuration Rereference page](https://the-guild.dev/graphql/hive/docs/api-reference/gateway-config)
for more details.
```js filename="index.js"
import { createGatewayRuntime } from '@graphql-hive/gateway'
const gateway = createGatewayRuntime({
// Here any config available in `gateway.config.ts`.
})
```
## Distributed Caching
But you need to be aware of the limitations of these environments. For example, in-memory caching is
@ -23,42 +43,104 @@ Memcached.
Hive Gateway cannot import the required dependencies manually, and load the supergraph from the file
system. So if you are not using a schema registry such as Hive Gateway or Apollo GraphOS, we need to
save the supergraph as a code file (`supergraph.js` or `supergraph.ts`) and import it.
save the supergraph as a code file (`supergraph.js` or `supergraph.ts`) and import it. We also need
to manually configure the needed transports to communicate with subgraphs.
### Loading the subgraph transport
Gateway Transports are the key component of the gateway runtimes execution. It allows the gateway
to communicate with the subgraph.
For example @graphql-mesh/transport-rest is used to communicate with the REST subgraphs generated by
OpenAPI and JSON Schema source handlers. And GraphQL subgraphs use GraphQL HTTP
Transport(@graphql-mesh/transport-http).
To avoid loading unnecessary transports and allow to provide your own transport, Hive Gateway is
loading those modules dynamically. This means that the bundler can't know statically that the
transport packages should be included in the bundle.
When running in a bundled environment like Serevless and Edge, you need to statically configure the
transports needed to comunicate with your upstream services. This way, the transport modules are
statically referenced and will be included into the bundle.
```ts filename="index.ts"
import { createGatewayRuntime } from '@graphql-hive/gateway'
import http from '@graphql-mesh/transport-http'
import supergraph from './supergraph'
const gatewayRuntime = createGatewayRuntime({
supergraph,
transports: {
// Add here every transports used by subgraphs
http // For example, the `http` transport for GraphQL based subgraphs.
}
})
export default { fetch: gatewayRuntime }
```
### Loading the supergraph from a file
For example, in GraphQL Mesh you need to save the supergraph as a TypeScript file:
Since the file system is not available, we need to find a way to include the supergraph in our code.
```ts filename="gateway.config.ts"
For this, we will need to have our supergraph SDL in a `.js` or a `.ts` file, so that we can import
it in our script.
```ts
import { createGatewayRuntime } from '@graphql-hive/gateway'
import http from '@graphql-mesh/transport-http'
import supergraph from './supergraph.js'
const serveRuntime = createGatewayRuntime({
supergraph,
transports: {
http // Let's say our subgraphs are using the standard graphql over HTTP transport.
}
})
```
We explain in following sections how to obtain a supergraph as a `.js` or `.ts` file.
#### Compose supergraph with Mesh
GraphQL Mesh can save the supergraph as a JavaScript file by providing an output file name ending
with `.js`:
```ts filename="mesh.config.ts"
import { defineConfig } from '@graphql-mesh/compose-cli'
export const composeConfig = defineConfig({
output: 'supergraph.ts',
output: 'supergraph.js',
subgraph: [
//...
]
})
```
In `supergraph.ts` file, you need to export the supergraph:
You can then generate the supergraph file using the `mesh-compose` CLI:
```bash
$ npx mesh-compose supergrpah
```
#### Compose supegraph with Apollo Rover
Apollo Rover only allow to export supegergraph as a GraphQL document, so we will have to wrap this
output into a JavaScript file:
```bash
$ echo "export default /* GraphQL */ \`$(rover supergraph compose)\`;"
```
#### Compose with other method
A generic way to turn a supergraph into a JavaScript file is to do it by hand.
In a `supergraph.js` file, you need to export the supergraph:
```ts
export default /* GraphQL */ `
#...
# Place your supergraph SDL here
`
```
Then you need to import the supergraph in your serverless function:
```ts
import { createGatewayRuntime, WSTransport } from '@graphql-hive/gateway'
// Let's say you are using WS transport
import supergraph from './supergraph.js'
const serveRuntime = createGatewayRuntime({
supergraph,
transports: {
ws: WSTransport
}
})
```