# Using Registry

## CDN Access

With high-availability and multi-zone CDN service based on Cloudflare, Hive allows you to access the registry, through a secured external service, that's always up regardless of Hive services.

To connect your GraphQL Gateway or any other tool with GraphQL Hive you need to generate an access key to our CDN.

Go to the schema view of your target https://app.graphql-hive.com/:org/:project/:target and click "Connect".

![Connect button](/schema-view-connect-button.png)

GraphQL Hive will now generate a unique key:

![Connect to CDN modal](/connect-to-cdn-modal.png)

## Apollo Federation

There are gateways maintained by Apollo team, [Apollo Gateway](#apollo-gateway) and [Apollo Router](#apollo-router). GraphQL Hive supports both!

### Apollo Gateway

- `HIVE_CDN_ENDPOINT` - the endpoint Hive generated for you in the previous step
- `HIVE_CDN_KEY` - the access key

```typescript
import { createSupergraphManager } from '@graphql-hive/client'
import { ApolloGateway } from '@apollo/gateway'
import { ApolloServer } from 'apollo-server'

const gateway = new ApolloGateway({
  // Apollo Gateway will fetch Supergraph from GraphQL Hive CDN
  supergraphSdl: createSupergraphManager({
    endpoint: process.env.HIVE_CDN_ENDPOINT,
    key: process.env.HIVE_CDN_KEY,
    pollIntervalInMs: 15_000
  })
})

const server = new ApolloServer({
  gateway
})

server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`)
})
```

### Apollo Router

GraphQL Hive ships a custom version of [Apollo Router](https://www.apollographql.com/docs/router/). The reason is that in order to extend Apollo Router, we need to write [a native Rust plugin](https://www.apollographql.com/docs/router/customizations/native).

Download Apollo Router for Linux (x86_64), MacOS (x86_64) or Windows (x86_64):

```bash
curl -fsSL https://graphql-hive.com/apollo-router-download.sh | bash
```

Start the router:

```bash
HIVE_CDN_ENDPOINT="..." HIVE_CDN_KEY="..." ./router
```

- `HIVE_CDN_ENDPOINT` - the endpoint Hive generated for you in the previous step
- `HIVE_CDN_KEY` - the access key

> Apollo Router polls schema from the registry every 10 seconds. In order to change it to 15 seconds pass: `HIVE_CDN_POLL_INTERVAL=15`.

## Schema Stitching

Stitching could be done in many ways, that's why `@graphql-hive/client` provides generic functions, not something dedicated for stitching. Unfortunately the implementation of gateway is up to you.

Here's an example of how it could work

```typescript
import { createServicesFetcher } from '@graphql-hive/client'
import { stitchSchemas } from '@graphql-tools/stitch'
import { UrlLoader } from '@graphql-tools/url-loader'
import { buildSchema } from 'graphql'
import { createServer } from '@graphql-yoga/node'

const urlLoader = new UrlLoader()

const fetchServices = createServicesFetcher({
  endpoint: process.env.HIVE_CDN_ENDPOINT,
  key: process.env.HIVE_CDN_KEY
})

async function main() {
  const services = await fetchServices()
  const subschemas = services.map(service => {
    return {
      schema: buildSchema(service.sdl),
      executor: urlLoader.getExecutorAsync(service.url)
    }
  })
  const schema = stitchSchemas({
    subschemas
  })

  const server = createServer({ schema })
  await server.start()
}

main().catch(err => {
  console.error(err)
  process.exit(1)
})
```

- `HIVE_CDN_ENDPOINT` - the endpoint Hive generated for you in the previous step
- `HIVE_CDN_KEY` - the access key

The `createServicesFetcher` factory function returns another function that is responsible for fetching a list of services from Hive's high-availability endpoint..

## Other tools

Here's a list of available endpoints:

### Federation

- list of services - `<endpoint>/schema`
- supergraph - `<endpoint>/supergraph`

### Stitching

- list of services - `<endpoint>/schema`

### Single schema project

- Schema Information `<endpoint>/schema`

  Here's an example of how it could work via cURL for a single schema project:

  ```bash
  curl --request GET \
    --url https://cdn.graphql-hive.com/asce7c12-753d-hive-bee-d7f2c803e232/schema \
    --header 'X-Hive-CDN-Key: aabTxbEyC78NvSPQNO+qLrrRnBvODJJ8k4sL/2EtIwc=' \
    --header 'Accept: application/json'
  ```

  Output:

  ```json
  {
    "sdl": "<SDL-here>",
    "date": "2021-08-20T15:16:40.024Z"
  }
  ```

- Raw SDL `<endpoint>/sdl`

  If you wish to get the raw SDL, without a wrapping JSON object, you can specify `/sdl` as suffix to your request.

- Introspection JSON `<endpoint>/introspection`

  If you wish to get the introspection JSON for your GraphQL schema, without a wrapping JSON object, you can specify `/introspection` as suffix to your request.
  This could be useful for tools that need to get the introspection as-is, like GraphQL Codegen, or GraphQL-Config.

- Metadata `<endpoint>/metadata`

  To fetch metadata published along with your GraphQL schema (using `--metadata`), use `/metadata` endpoint

  ```bash
  curl --request GET \
    --url https://cdn.graphql-hive.com/asce7c12-753d-hive-bee-d7f2c803e232/metadata \
    --header 'X-Hive-CDN-Key: YOUR_KEY_HERE'
  ```

  The value returned is the value you stored, as JSON, with `Content-Type: application/json` header.

## Notes

### ETag and If-None-Match headers

The CDN service accepts the [`ETag`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag) and [`If-None-Match`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match) headers.

Every successful response from the CDN service (`200 OK`) contains the `ETag` header with a checksum.
If you send the same checksum in the `If-None-Match` header, the CDN service will return `304 Not Modified`, but only if the data hasn't changed.
If the data has changed, the CDN service will return `200 OK` with the new data and new `ETag` header.

Using `ETag` and `If-None-Mathc` helps to prevent unnecessary data transfer.

The `@graphql-hive/client` package uses this feature to save bandwidth and improve performance.
