import NextImage from 'next/image'
import { Callout, Cards } from '@theguild/components'
import schemaHistoryDiffImage from '../../../../public/docs/pages/features/history-diff.png'
import schemaHistoryImage from '../../../../public/docs/pages/guides/history.png'

# Schema Registry

Hive as a schema registry serves the main purpose of preventing breaking changes. This ensures that
your GraphQL API stays up-to-date and running smoothly. This allows you to plan ahead and make the
necessary modifications to your schema in a timely manner.

However, it is important to note that determining what constitutes a breaking change can be a
complex task. It requires a thorough understanding of your GraphQL API, consumers and real-world
traffic patterns. Hive provides a set of tools to help you with this task.

## What is a breaking change?

A breaking change in the API ecosysten, is a change that will break the existing consumers of the
API, and will cause a distruption.

Since the GraphQL language (called SDL) is fully static and strongly typed, it is possible to
determine if a change could be a breaking change.

Here's an example for a change in a GraphQL schema that could be considered a breaking change:

```diff copy=false
type Query {
  posts: [Post]
}

type Post {
  id: ID!
  title: String!
  content: String!
-  description: String!
}
```

In this example, we removed the `description` field from the `Post` type. This is a breaking change
because consumers who depend on the `description` field in their GraphQL operations (queries,
mutations, subscriptions) will now fail to execute.

This is one example of many supported kinds of possible breaking changes. Hive is using
[GraphQL-Inspector](https://the-guild.dev/graphql/inspector) under the hood.

## Breaking changes in practice

In practice, breaking changes are not always breaking. This is because consumers of your GraphQL API
might not be using the field that was removed.

For example, let's assume we have the following GraphQL operation:

```graphql
query Feed_AllPosts {
  posts {
    id
    title
    content
    # Note: Field "description" is not requested in this query
  }
}
```

In this case, the removal of the `description` field is not a breaking change, because the consumer
of the API is not using this field.

Hive is smart enough to understand this, and will not consider this change as a breaking change.
Please, follow the
[Conditional Breaking Changes](/docs/management/targets#conditional-breaking-changes) guide to
enable this feature in your target.

From now on, when a new schema of your GraphQL schema is published to the registry, Hive uses the
data collected from your API gateway to identify whether the change in your schema actually affects
consumers.

## Supported Schema Models

Hive supports the following project types:

- **Single Schema**: a GraphQL project that has a single GraphQL schema developed as a standalone.
  This setup works for most frameworks and tools in the GraphQL ecosystem.
- **Schema Stitching**: a form of remote schema merging allowing developers to merge any GraphQL
  schema(s), under one or many gateways. You can use either direct
  [Schema Stitching](https://the-guild.dev/graphql/stitching) or [Hive gateway](/docs/gateway) for
  this project type.
- **Apollo Federation**: a form of remote schema merging developed according to the
  [Federation specification](https://www.apollographql.com/docs/federation/subgraph-spec/).

If you wish to learn more about how to use Hive with each of these project types, please refer to
the following guides:

<Cards>
  <Cards.Card arrow title="Single Schema" href="/docs/get-started/single-project" />
  <Cards.Card arrow title="Schema-Stitching" href="/docs/get-started/schema-stitching" />
  <Cards.Card arrow title="Apollo Federation" href="/docs/get-started/apollo-federation" />
</Cards>

## Actions on schemas

This section covers the actions that can be performed on GraphQL schemas in Hive. Action of schemas
can be performed using the [Hive CLI](/docs/api-reference/cli) or through the
[Hive Client](/docs/api-reference/client).

### Publish a schema

Publishing a schema is the form of registering a new schema in Hive.

Every schema published to Hive consists of the following data (depends on project type):

|                    | Single Schema | Schema Stitching | Apollo Federation |
| ------------------ | ------------- | ---------------- | ----------------- |
| Version Identifier | ✓             | ✓                | ✓                 |
| Author             | ✓             | ✓                | ✓                 |
| Schema SDL         | ✓             | ✓                | ✓                 |
| Hive Metadata      | ✓             | ✓                | ✘                 |
| Service Name       | ✘             | ✓                | ✓                 |
| Service URL        | ✘             | ✓                | ✓                 |

Here's an overview of what each of these steps means:

- **Version Identifier**: usually a unique identifier for the schema version. This can a git commit
  hash, or any other unique identifier that you wish to use.
- **Author**: the author of the change. This can be a name, an email, or any other identifier. You
  can use Git author information for this field.
- **Schema SDL**: the GraphQL schema in SDL format.
- **Hive Metadata**: Hive metadata is an optional JSON object you can attach to every published
  schema. You can include any information you wish to include in this JSON object (see
  [Publishing Hive metadata](/docs/api-reference/cli#hive-metadata)).
- **Service Name**: the name of the service. This is used for Schema-Stitching and Apollo Federation
  only.
- **Service URL**: the URL of the service. This is used for Schema-Stitching and Apollo Federation
  only.

Every schema published to Hive is going through a process of validation, the following steps are
performed to ensure a schema is fully valid:

1. **SDL Parse** - the schema is parsed and validated against the GraphQL SDL specification.
2. **SDL Validate** - the schema is validated against the GraphQL specification.
3. **Metadata validation** - if a metadata was published, a JSON schema validation is performed to
   ensure the metadata is a fully valid JSON object.
4. **Composition Checks** - if the project type is Schema-Stitching or Apollo Federation, the schema
   is validated against the composition rules of the project type.
5. **Schema Changes** - A schema `diff` is calculated and compared against the previous schema
   version. If [Conditional Breaking Changes](/docs/management/targets#conditional-breaking-changes)
   is activated, an additional phase of check against collected operations is performed.

For additional reading:

- [Publishing a schema using Hive CLI](/docs/api-reference/cli#publish-a-schema)
- [`schema:publish` command reference](/docs/api-reference/cli#hive-schemapublish-file)
- [Publishing a schema using Hive Client](/docs/api-reference/client)

### Check a schema

Checking a GraphQL schema is the form of checking the compatbility of an upcoming schema, compared
to the latest published version.

This process of checking a schema needs to be done before **publishing** a new schema version. This
is usually done as part of a CI/CD pipeline, and as part of Pull Request flow.

Every schema checked to Hive is going through a process of validation, the following steps are
performed to ensure a schema is valid:

1. **SDL Parse** - the schema is parsed and validated against the GraphQL SDL specification.
2. **SDL Validate** - the schema is validated against the GraphQL specification.
3. **Composition Checks** - if the project type is Schema-Stitching or Apollo Federation, the schema
   is validated against the composition rules of the project type.
4. **Schema Changes** - A schema `diff` is calculated and compared against the previous schema
   version. If [Conditional Breaking Changes](/docs/management/targets#conditional-breaking-changes)
   is activated, an additional phase of check against collected operations is performed. If a
   non-safe change has been introduced in the schema check, it will be rejected by Hive.

For additional reading:

- [Checking a schema using Hive CLI](/docs/api-reference/cli#check-a-schema)

### Approve breaking schema changes

Sometimes, you want to allow a breaking change to be published to the registry. This can be done by
manually approving a failed schema check on the Hive App.

By approving a schema check. You confirm that you are aware of the breaking changes within the
schema check, and want to retain that approval within the context of a pull/merge request or branch
lifecycle.

In order to retain the approval of the breaking changes, additional configuration is required. See
[Checking a schema using Hive CLI](/docs/api-reference/cli#check-a-schema).

### Fetch a schema

Sometimes it is useful to fetch a schema (SDL or Supergraph) from Hive, for example, to use it in a
local development. This can be done using the `schema:fetch` command.

<Callout type="info">
  Don't confuse this with the [high-availability CDN](/docs/high-availability-cdn.mdx). This command
  is used to fetch a schema from the API where the CDN always represents the latest valid schema.
</Callout>

- [Fetch a schema using Hive CLI](/docs/api-reference/cli#fetch-a-schema-from-the-registry)

### Delete a service

<Callout type="info">
  This action is only available for Schema-Stitching and Apollo Federation projects.
</Callout>

Deleting a service is the form of removing a service from the multi-schema project.

For additional reading:

- [Deleting a service using Hive CLI](/docs/api-reference/cli#delete-a-schema)
- [`schema:delete` command reference](/docs/api-reference/cli#hive-schemadelete-service)

## Schema History and Changelog

The Hive Schema History consists of a list of all published schemas, and their respective changes.

In the list of schema versions of changes, you'll be able to see the following information:

- **Version Identifier**: the version identifier of the schema.
- **Author**: the author of the change.
- **Date**: the date of the change.
- **Status**: the status of the change and the validity of the schema.
- **Associated Git Commit**: the Git commit associated with the change, when
  [GitHub Integration](/docs/management/organizations#github) is enabled for your organization, and
  a [GitHub repository is linked to the Hive project](/docs/management/projects#github-repository).

### Changelog View

You can inspect a change in your GraphQL schema using the Changelog view. This view provides you an
overview of the changes, and their respective impact on your GraphQL schema:

<NextImage
  alt="Schema History Changelog"
  src={schemaHistoryImage}
  className="mt-6 max-w-2xl rounded-lg drop-shadow-md"
/>

### Diff View

If you wish to have a more technical view of the changes, you can use the `diff` view:

<NextImage
  alt="Schema History Diff"
  src={schemaHistoryDiffImage}
  className="mt-6 max-w-2xl rounded-lg drop-shadow-md"
/>
