The point of this sample is to demonstrate a full example of automatically importing the schema types from Hasura into a remote schema, to allow usage of Hasura types in a remote schema.
Additionally, there is a utility for matching the remote schema's role permissions to the hasura schema role permissions.
This is accomplished using the graphql-codegen
package. See "Points of Interest" below for specifics.
├── hasura - metadata and databse definitions for hasura container
│ ├── metadata
│ ├── migrations
│ └── seeds
├── migrations - knex-based migration definitions
│ ├── migrations
│ └── seeds
└── server - apollo-server backend, proxied to with graphql from hasura and remote schema stitching back
└── src
├── exceptions
├── graphql
│ ├── local - apollo-server graphql schema, types, and resolvers
│ │ └── resolvers
│ └── remote - remote hasura graphql operations
│ ├── mutations
│ ├── queries
│ └── utils - helpers for managing remote schema permissions
├── middlewares
├── services - functionality pertaining to local/resolvers implementations, does the heavy lifting for custom apollo-server resolvers
└── utils
For a minimum setup to include automatic schema codegen (assuming you have an apollo-server instance already), look at the following files:
Codegen:
server/package.json - includes `run` commands for graphql-codegen
server/codegen-remote.yml - Hasura graphql config
server/codegen-local.yml - Apollo-server graphql config
server/src/graphql/local/file-loader.js - Custom loader to remove the schema type definitions from the hasura schema
Custom remote schema types:
server/src/graphql/local/localTypes.ts - Your apollo-server operations that will get merged into Hasura. NOTE: at least one `Query` operation is required
server/src/graphql/local/graphql.schema-remote.graphql - Hasura schema, stripped of the schema type (generated by codegen-remote.yml)
server/src/graphql/local/graphql.schema.graphql - Apollo-server schema, incorporating stripped Hasura schema types
Custom resolvers:
server/src/graphql/local/resolvers/usersResolvers.ts - Custom resolver for mutation seen in localTypes.ts above
Custom services (optional, depending on how one wishes to implement their resolvers):
server/src/services/users.service.ts - Service pattern for delegating actual resolver business logic
Apollo-server config:
server/src/app.ts - Imports and merges types and resolvers. See initializeApollo()
$ cd server
$ npm run generate # generate local and remote
$ npm run generate-l # generate local
$ npm run generate-r # generate remote
!!After updating the apollo-server schema, be sure to reload the remote schema in Hasura!!
Note: this repository assumes the name of the remote schema is apollo-server
. Change this by changing the HASURA_REMOTE_SCHEMA_NAME
parameter in the .env
root file.
If changes to the hasura role permissions cause a metadata conflict with the remote schema permissions, first drop the remote schema:
(from ./server
)
$ npm run hasura:remove_schema # remove remote schema from hasura.
Make necessary changes to the hasura role permissions, then re-add the remote schema:
(from ./server
)
$ npm run hasura:add_schema # add remote schema to hasura
Then, configure the allowed operations in the roles
const in server/src/graphql/remote/utils/add_remote_schema_permissions.ts
. The object is structed as follows:
const roles = {
user: {
Query: ["required"],
Mutation: [
"user_set_username_via_remote_schema"
],
Subscription: [""]
}
}
The above example would allow the user
role to call the required
query, and the user_set_username_via_remote_schema
mutation. Configure as fits your use case.
Then, generate the permissions:
(from ./server
)
$ npm run hasura:add_schema_permissions # add remote schema permissions to hasura
Setup ENV
$ cp .env.sample .env
Customize values as required.
Install required software:
$ install docker and docker-compose (depends on system)
Setup containers and volumes:
$ sudo docker-compose build
$ sudo docker-compose volume create db
Start postgres first:
$ sudo docker-compose up db
Setup database:
$ cd migrations
$ npm install
$ npx knex migrate:latest
$ npx knex seed:run --specific=seed_user.js
Ctrl+c docker-compose and start up everything:
$ sudo docker-compose up
Import the hasura metadata:
# install hasura CLI
$ curl -L https://github.com/hasura/graphql-engine/raw/stable/cli/get.sh | bash
$ cd hasura
$ hasura metadata appy --admin-secret <hasura_admin_secret>
Go to the Hasura CLI at http://127.0.0.1:8080 and you should see the custom mutation in the graphiql explorer pane. Try running it, eg:
mutation MyMutation {
user_set_username_via_remote_schema(jwt_uid: "abcdefghijklmnop", username: "abcd") {
updated_at
username
}
}