Graphql

node v8.17.0
version: 1.0.0
endpointsharetweet
POC for bigchaindb-graphql interface
require("core-js") const bip39 = require("bip39") const driver = require("bigchaindb-driver") const bodyParser = require("body-parser") const fetch = require("node-fetch")
Graphql dependencies
const { GraphQLServer } = require("graphql-yoga") const { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLInt, GraphQLList, GraphQLBoolean } = require("graphql") require("graphql-tools") const GraphQLJSON = require("graphql-type-json")
Constants
const gql = String.raw const posts = [] let idCount = 0
Type Definitions for Graphl Instance
const typeDefs = gql` type Query { posts: [Post!]! post(id: ID!): Post description: String! version: String } type Mutation { createDraft(title: String!, content: String): Post deletePost(id: ID!): Post publish(id: ID!): Post } type Post { id: ID! title: String! content: String! published: Boolean! }`
Graphql Resolvers: functionally map data to Graphql field
const resolvers = { Query: { version: () => `0.0.1`, description: () => `This is the Blockproof Graphql interface`, posts: () => posts, post: (parent, args) => posts.find(post => post.id === args.id) }, Mutation: { createDraft: (parent, args) => { const post = { id: `post_${idCount++}`, title: args.title, content: args.content, published: false } posts.push(post) return post }, deletePost: (parent, args) => { const postIndex = posts.findIndex(post => post.id === args.id) if (postIndex > -1) { const deleted = posts.splice(postIndex, 1) return deleted[0] } return null }, publish: (parent, args) => { const postIndex = posts.findIndex(post => post.id === args.id) posts[postIndex].published = true return posts[postIndex] } } }
Bigchain connection
class BigchainConnection { constructor (path, headers = {}) { this.path = path this.headers = Object.assign({}, headers) this.conn = new driver.Connection(path, headers) } getTransaction(transactionId) { return this.conn.getTransaction(transactionId) } listTransactions(assetId, operation) { return this.conn.listTransactions(assetId, operation) } listOutputs(publicKey, spent) { return this.conn.listOutputs(publicKey, spent) } getBlock(blockId) { return this.conn.getBlock(blockId) } listBlocks(transactionId) { return this.conn.listBlocks(transactionId) .then(blockIds => Promise.all(blockIds.map(blockId => this.conn.getBlock(blockId)))) } listVotes(blockId) { return this.conn.listVotes(blockId) } searchAssets(text) { return this.conn.searchAssets(text) .then(assetList => Promise.all(assetList.map(asset => this.conn.getTransaction(asset.id)))) } }
Bigchain Schema
Let's break up the types
class BigchainSchema { constructor (conn) { this.FulfillsType = new GraphQLObjectType({ name: 'Fulfills', fields: () => ({ output_index: { type: GraphQLInt }, transaction: { type: this.TransactionType, resolve (root) { return conn.getTransaction (root.transaction_id) } } }) }) this.InputType = new GraphQLObjectType ({ name: 'Input', fields: { owners_before: { type: new GraphQLList (GraphQLString) }, fulfillment: { type: GraphQLString }, fulfills: { type: this.FulfillsType } } }) this.OutputType = new GraphQLObjectType({ name: 'Output', fields: { condition: { type: GraphQLJSON }, public_keys: { type: new GraphQLList(GraphQLString) }, amount: { type: GraphQLString } } }) this.TransactionType = new GraphQLObjectType({ name: 'Transaction', fields: () => ({ id: { type: GraphQLString }, operation: { type: GraphQLString }, version: { type: GraphQLString }, asset: { type: GraphQLJSON }, metadata: { type: GraphQLJSON }, inputs: { type: new GraphQLList(this.InputType) }, outputs: { type: new GraphQLList(this.OutputType) }, blocks: { type: new GraphQLList(this.BlockType), resolve(root) { return conn.listBlocks(root.id) } } }) }) this.VoteType = new GraphQLObjectType({ name: 'Vote', fields: { node_pubkey: { type: GraphQLString }, signature: { type: GraphQLString }, vote: { type: new GraphQLObjectType({ name: 'VoteIntern', fields: { voting_for_block: { type: GraphQLString }, previous_block: { type: GraphQLString }, is_block_valid: { type: GraphQLBoolean }, invalid_reason: { type: GraphQLString }, timestamp: { type: GraphQLString } } }) } } }) this.BlockType = new GraphQLObjectType({ name: 'Block', fields: { id: { type: GraphQLString }, block: { type: new GraphQLObjectType({ name: 'BlockIntern', fields: { timestamp: { type: GraphQLString }, transactions: { type: new GraphQLList(this.TransactionType) }, node_pubkey: { type: GraphQLString }, voters: { type: new GraphQLList(GraphQLString) }, } }) }, votes: { type: new GraphQLList(this.VoteType), resolve(root) { return conn.listVotes(root.id) } }, signature: { type: GraphQLString } } }) this.queryType = new GraphQLObjectType({ name: 'Query', fields: { transaction: { type: this.TransactionType, args: { id: { type: GraphQLString } }, resolve(root, { id }) { return conn.getTransaction(id) } }, transactions: { type: new GraphQLList(this.TransactionType), args: { asset_id: { type: GraphQLString }, operation: { type: GraphQLString } }, resolve(root, { asset_id, operation }) { // eslint-disable-line camelcase return conn.listTransactions(asset_id, operation) } }, outputs: { type: new GraphQLList(this.FulfillsType), args: { public_key: { type: GraphQLString }, spent: { type: GraphQLBoolean } }, resolve(root, { public_key, spent }) { // eslint-disable-line camelcase return conn.listOutputs(public_key, spent) } }, block: { type: this.BlockType, args: { id: { type: GraphQLString } }, resolve(root, { id }) { return conn.getBlock(id) } }, blocks: { type: new GraphQLList(this.BlockType), args: { transaction_id: { type: GraphQLString }, status: { type: GraphQLString }, }, resolve(root, { transaction_id, status }) { // eslint-disable-line camelcase return conn.listBlocks(transaction_id, status) } }, votes: { type: new GraphQLList(this.VoteType), args: { block_id: { type: GraphQLString }, }, resolve(root, { block_id }) { // eslint-disable-line camelcase return conn.listVotes(block_id) } }, search: { type: new GraphQLList(this.TransactionType), args: { text: { type: GraphQLString } }, resolve(root, { text }) { return conn.searchAssets(text) } } } }) this.schema = new GraphQLSchema({ query: this.queryType, // mutation: this.mutationType, types: [this.TransactionType], }) } }
Calls connection for getTransaction, listTransaction, listOutputs, getBlock, listBlocks, and searchAssets
const server = new GraphQLServer({ typeDefs: typeDefs, resolvers: resolvers })
Endpoint for Graphql and Graphiql
server.start(() => console.log(`Yoga running on http://localhost:4000`))
Loading…

no comments

    sign in to comment