bitshares / bitshares-core

BitShares Blockchain node and command-line wallet
https://bitshares.github.io/
Other
1.17k stars 647 forks source link

GraphQL plugin #1827

Open scientistnik opened 5 years ago

scientistnik commented 5 years ago

What you think about implement GraphQL plugin to bitshares-core?

GraphQL allow make requests for data you need. For example, if I need get orders and balances of account. I call:

get_full_accounts(['scientistnik'], false)

I get:

[ 'account',
  'statistics',
  'registrar_name',
  'referrer_name',
  'lifetime_referrer_name',
  'votes',
  'cashback_balance',
  'balances',
  'vesting_balances',
  'limit_orders',
  'call_orders',
  'settle_orders',
  'proposals',
  'assets',
  'withdraws',
  'htlcs']

But, I need only balances and limit_orders. In GraphQL:

{
  account(name='scientistnik') {
    balances {
      asset_id
      amount
    }
    limit_orders {
      for_sale
      sell_price
    }
  }
}
pmconrad commented 5 years ago

I think it would require a lot of effort for very little savings in bandwidth. Probably not worth the trouble. Or do you see any other significant advantages?

clockworkgr commented 5 years ago

We've discussed this in UI team before, but as a separate setup (e.g. apollo) combined with an API proxying (and possibly caching) server

scientistnik commented 5 years ago

@pmconrad you right, it don't have significant advantages. Convenience only.

For example, we may define Account and Asset GraphQL types:

type Account {
  id: String!
  name: String!
  registrar: String!
  balances: [AssetAmount!]!
  ...
}

type Asset {
  id: String!
  symbol: String!
  precision: Int!
  holders(start: Int!, limit: Int!):[Account!]!
  ...
}

AssetAmount is

type AssetAmount {
  asset: Asset!,
  amount: Int!
}

Now, we may send one request for get all information what we need:

query {
  account(id: "1.2.440272") {
    id
    name
    balances {
      amount
      asset {
        symbol
        holders(start: 0, limit: 10) {
          id
          name
        }
      }
    }
  }
}

If we define several types for market data, almost all information can get from one query!

query {
  market(base: "BTS", quote: "USD") {
    ticker {
      baseVolume
      quoteVolume
      latest
      ...
    }
    history {
      ...
    }
    order(limit: 10) {
      ...
    }
    orderBook(limit: 5) {
      ...
    }
  }
}
pmconrad commented 5 years ago

Who is "we" in the example above? The client? Or is this implemented in the plugin you're proposing?

Are you talking about defining a GraphQL-based API and providing an implementation for it, or is there a ready-made generic GraphQL server that would have to interface with our internal database?

A generic API where the client specifies what and how much it wants is dangerous because it opens up new DoS attack vectors. OTOH if only predefined queries are allowed (and have to be implemented manually one by one) I still don't see significant advantages over our current API.