import { Callout, PackageCmd } from '@theguild/components'

# Publishing new schema

Once you have created the target, the next step would be typically to push the GraphQL schema to Hive against the respective target.

## Requirements

- An active [token](./tokens)

## Using Hive CLI

### NPM

Install [`@graphql-hive/cli`](https://www.npmjs.com/package/@graphql-hive/cli) package from NPM:

<PackageCmd packages={['-D @graphql-hive/cli']} />

### Linux / MacOS

Install latest version:

```bash
curl -sSL https://graphql-hive.com/install.sh | sh
```

Now, create a config file as `hive.json` and paste there your token:

```json
{
  "token": "YOUR-TOKEN"
}
```

<Callout>
  Having a config file is not mandatory, you can use `--token YOUR-TOKEN` or an environment variable called `HIVE_TOKEN`
  instead.
</Callout>

To publish a schema, use `hive schema:publish` command:

```bash
# Single GraphQL API
hive schema:publish schema.graphql
# or
hive schema:publish "src/*.graphql"

# Federation or Stitching
hive schema:publish --service reviews schema.graphql

# If you need service endpoint details (Federation/Stitching), add --url:
hive schema:publish --service reviews --url http://my-service.com/graphql schema.graphql
```

<Callout>To force publishing a schema, enable `--force` flag.</Callout>

Once the schema is published, you should be able to see it in: `http://app.graphql-hive.com/<your-org>/<your-project>/<your-target>`.

### Publishing Metadata

If your GraphQL schema runtime requires any metadata to run, you can attach metadata to your schema publication.

Metadata published to Hive must be a valid JSON, and limited to 25MB.

To do that, you can use `--metadata` flag when publishing:

```bash
# Using a file
hive schema:publish schema.graphql --metadata metadata.json
# or inline
hive schema:publish schema.graphql --metadata '{ "someData": true }'
```

To fetch the metadata later, use the Hive CDN, see [Using the Registry with any tool](./registry-usage#other-tools).

## Using Hive Client

Our [`@graphql-hive/client`](https://www.npmjs.com/package/@graphql-hive/client) comes with a generic client and plugins for [Envelop](https://envelop.dev) and [Apollo Server](https://github.com/apollographql/apollo-server).

<PackageCmd packages={['@graphql-hive/client']} />

### Apollo Server

Thanks to the plugin system it's a matter of adding `hiveApollo` plugin to `ApolloServer` instance:

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

const server = new ApolloServer({
  typeDefs,
  resolvers,
  plugins: [
    hiveApollo({
      enabled: true,
      debug: true, // or false
      token: 'YOUR-TOKEN',
      reporting: {
        // feel free to set dummy values here
        author: 'Author of the latest change',
        commit: 'git sha or any identifier',

        // Federation and Stitching
        serviceUrl: '...',
        serviceName: '...'
      }
    })
  ]
})
```

### Envelop

If you're not familiar with Envelop - in "short" it's a lightweight JavaScript library for wrapping GraphQL execution layer and flow, allowing developers to develop, share and collaborate on GraphQL-related plugins, while filling the missing pieces in GraphQL implementations.

Here's [more](https://www.envelop.dev/docs) on that topic.

```typescript
import { envelop } from '@envelop/core'
import { useHive } from '@graphql-hive/client'

const envelopProxy = envelop({
  plugins: [
    useHive({
      enabled: true,
      debug: true, // or false
      token: 'YOUR-TOKEN',
      reporting: {
        // feel free to set dummy values here
        author: 'Author of the schema version',
        commit: 'git sha or any identifier'
      }
    })
  ]
})
```

### Other Node.js servers

First, `createHive` to instantiate the Hive Client.

The `reportSchema` should be called once or every time you change the schema.

```typescript
import express from 'express'
import { graphqlHTTP } from 'express-graphql'
import { createHive } from '@graphql-hive/client'

const app = express()
const hive = createHive({
  enabled: true,
  debug: true, // or false
  token: 'YOUR-TOKEN',
  reporting: {
    // feel free to set dummy values here
    author: 'Author of the schema version',
    commit: 'git sha or any identifier'
  }
})

hive.reportSchema({ schema: yourSchema })

app.post('/graphql', graphqlHTTP({ schema: yourSchema }))
```

### GraphQL Ruby

Add `GraphQL::Hive` **at the end** of your schema definition:

```ruby
class Schema < GraphQL::Schema
  query QueryType

  use(
      GraphQL::Hive,
      {
        token: '<YOUR_TOKEN>',
        reporting: {
          # feel free to set dummy values here
          author: 'Author of the schema version',
          commit: 'git sha or any identifier'
        },
      }
  )
end

```

More information is available on the `graphql-hive` repository: https://github.com/charlypoly/graphql-ruby-hive

## GitHub Integration

In case you want to integrate GraphQL Hive with your GitHub repository, follow the [GitHub integration guide](./integrations#github).

![GitHub Schema Check](/github-schema-check.png)
