# Run Anywhere - Deploy your Gateway

import { Callout } from '@theguild/components'

Once you configured, and tested your gateway. Now, it is time to deploy it. Hive Gateway Runtime
uses Web Standards (WHATWG Fetch API) not only as an HTTP client but also for handling the
server-side. That gives us the ability to run the gateway in any environment that runs JavaScript.

Node.js is the most common server-side environment in JavaScript ecosystem but it doesn't use Web
Standards for handling HTTP requests. So we use a library called
[`@whatwg-node/server`](https://github.com/ardatan/whatwg-node/tree/master/packages/server#whatwg-node-generic-server-adapter)
that allows us to create a wrapper between `node:http` and Fetch API.

<Callout>
Check the following sections to see how to deploy your gateway in different environments on the left menu.

If your environment is not listed, **that doesn't mean you can't deploy your gateway**. Thanks to
our adapter system, you can create your own implementation. See the
[Other Environments (not listed) section](#other-environments-not-listed) below.

</Callout>

## Programmatic Usage

In all of the deployment examples listed, **except for [Docker](/docs/gateway/deployment/docker) and
[Google Cloud Run](/docs/gateway/deployment/serverless/google-cloud-platform#cloud-run)**, you will
be using the Hive Gateway programmatically through its programmatic API.

The runtime of Hive Gateway, our recommended way of using the gateway programmatically comes in a
separate package `@graphql-hive/gateway-runtime`.

```sh npm2yarn
npm i @graphql-hive/gateway-runtime
```

Improving the experince of Hive Gateway in various JavaScript environments (especially
[serverless/on-the-edge](/docs/gateway/deployment/serverless)), the `@graphql-hive/gateway-runtime`
comes in a slimmer version set up for optimized runtime and smaller size. This leads to a difference
in the configuration options compared to the CLI version `@graphql-hive/gateway`.

See the [Hive Gateway Configuration Rereference](/docs/api-reference/gateway-config) for more
details about these differences.

<Callout>
  None of the transports and none of the built-in plugins are included in the slimmed down runtime
  version of the Hive Gateway `@graphql-hive/gateway-runtime`.
</Callout>

## Other Environments (Not Listed)

Let's say you have an environment that is not listed here, you can still deploy your Hive Gateway
using its progammatic API. In this case, we will show here how to pass the request information from
your environment to Hive Gateway, then get the response for your environment back.

```ts
import { createGatewayRuntime } from '@graphql-hive/gateway-runtime'
import type {
  ImaginaryEnvironmentRequest,
  ImaginaryEnvironmentServerContext
} from '@imaginary-environment/types'
import { getMySupergraph } from './my-supergraph.js'

// Initialise and configure the Hive Gateway runtime
const gateway = createGatewayRuntime<ImaginaryEnvironmentServerContext>({
  supergraph: () => getMySupergraph()
})

// Let's say it needs a function exported
export async function gatewayEndpoint(
  envRequest: ImaginaryEnvironmentRequest,
  envContext: ImaginaryEnvironmentServerContext
) {
  // The runtime provides a fetch function which has exactly the same signature with regular `fetch`
  const res = await gateway.fetch(
    envRequest.url,
    {
      method: envRequest.method,
      headers: envRequest.headers,
      body: envRequest.body // Body can be a string or a ReadableStream or UInt8Array, see [BodyInit](https://developer.mozilla.org/en-US/docs/Web/API/BodyInit)
    },
    envContext
  )

  // You can create an object from [`Headers`](https://developer.mozilla.org/en-US/docs/Web/API/Headers) object
  const headersObj: Record<string, string> = {}
  res.headers.forEach((value, key) => {
    headersObj[key] = value
  })
  // It returns [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) object
  // See the methods and properties of the Response object from the link
  // You can get a string
  const bodyText = await res.text()
  // You can get a stream
  const bodyStream = res.body
  // You can get a buffer
  const bodyBuffer = await res.arrayBuffer()
  // You can get a JSON object
  const bodyJson = await res.json()
  // You can get a blob
  const bodyBlob = await res.blob()
  // You can get a form data
  const bodyFormData = await res.formData()

  // Then you can return the response to your environment
  return {
    status: res.status,
    statusText: res.statusText,
    headers: headersObj,
    bodyText
  }
}
```
