# 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 here**, that doesn't mean you can't deploy your gateway. Thanks
to our adapter system, **you can create your own implementation for your environment**.

Feel free to contribute the documentation for your favorite server implementation if we don't have
it in the list.

</Callout>

## Other Environments (Custom)

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

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

// First pass it to the runtime as a context
const gatewayRuntime = createGatewayRuntime<ImaginaryEnvironmentServerContext>({
  supergraph: () => getMySupergraph()
})

// Let's say it needs a function exported
export async function gatewayEndpoint(
  envRequest: ImaginaryEnvironmentRequest,
  envContext: ImaginaryEnvironmentServerContext
) {
  // Serve Runtime provides a fetch function which has exactly the same signature with regular `fetch`
  const res = await gatewayRuntime.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
  }
}
```
