Skip to content

Instantly share code, notes, and snippets.

@brunocarvalhodearaujo
Forked from todkap/stitch-gist
Last active August 10, 2022 15:07
Show Gist options
  • Save brunocarvalhodearaujo/c10a4e02ec58e09857ae8a4f3b38fad5 to your computer and use it in GitHub Desktop.
Save brunocarvalhodearaujo/c10a4e02ec58e09857ae8a4f3b38fad5 to your computer and use it in GitHub Desktop.
const { makeRemoteExecutableSchema, introspectSchema, mergeSchemas } = require('graphql-tools')
const { createHttpLink } = require('apollo-link-http')
const { setContext } = require('apollo-link-context')
const { ApolloServer } = require('apollo-server-express')
const fetch = require('node-fetch')
const log4js = require('log4js')
const logger = log4js.getLogger('server.js')
logger.level = process.env.LOG_LEVEL || 'debug'
const express = require('express')
const app = express()
const _ = require('lodash')
const ACCOUNT_URI = process.env.BASE_URI || 'http://token-factory-account-service:4001' // override for not in K8
const REGISTRATION_URI = process.env.BASE_URI || 'http://token-factory-registration-service:4000' // override for not in K8
const STELLAR_NODE_URI = 'https://core-test.gly.sh/graphql'
let schema = false
// graphql API metadata
const graphqlApis = [
//Token Factory APIs will override this default set
{ uri: STELLAR_NODE_URI },
{ uri: ACCOUNT_URI + '/account' },
{ uri: REGISTRATION_URI + '/registration' }
]
// authenticate for schema usage
const context = ({ req }) => {
return { req }
}
// create executable schemas from remote GraphQL APIs
const createRemoteExecutableSchemas = async () => {
let schemas = []
for (const api of graphqlApis) {
const http = new createHttpLink({ uri: api.uri, fetch })
const link = setContext((request, previousContext) => {
return {
headers: {
authorization: previousContext.graphqlContext
? previousContext.graphqlContext.req.headers.authorization
: ''
}
}
}).concat(http)
const remoteSchema = await introspectSchema(link)
const remoteExecutableSchema = makeRemoteExecutableSchema({ schema: remoteSchema, link })
schemas.push(remoteExecutableSchema)
}
return schemas
}
const createNewSchema = async () => {
const schemas = await createRemoteExecutableSchemas()
if (!schemas) {
return false
}
return mergeSchemas({ schemas })
}
const port = 3001
const path = '/token-factory'
app.path = path
//Kub8 health check
app.get('/readiness', async function (req, res) {
try {
schema = await createNewSchema()
if (schema) {
const server = await new ApolloServer({ schema })
server.applyMiddleware({ app, path })
res
.status(200)
.json({ message: 'Graphql service is ready. All services are connected' })
} else {
res
.status(500)
.json({ err: 'Graphql service not ready. Waiting on services' })
}
} catch (error) {
console.log('error', error)
res
.status(500)
.json({ err: 'Graphql service is unreachable' })
}
})
app.get('/liveness', async function (req, res) {
try {
const tmpSchema = await createNewSchema()
if (tmpSchema && _.differenceBy(tmpSchema, schema).length === 0) {
res
.status(200)
.json({ message: 'Graphql service is alive and no changes to schema have occurred' })
} else {
res
.status(500)
.json({ err: 'Graphql schema has changed.' })
}
} catch (error) {
console.log('error', error)
res
.status(500)
.json({ err: 'Graphql service is unreachable' })
}
})
const startServer = async () => {
app.listen({ port: port }, () => {
logger.info(`App listening on <hostname>:${port}${app.path}!`)
})
try {
schema = await createNewSchema()
if (schema) {
const server = new ApolloServer({ schema, context })
logger.info('schema merged', schema)
server.applyMiddleware({ app, path })
}
} catch (error) {
logger.info(
'Failed to create schema during startup. Defer to K8 probes',
error
)
}
}
startServer()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment