02.24 实战比特币实时价格GraphQL API「Node.JS」

在这篇文章中,我们将学习如何使用Node.js开发一个比特币 实时价格行情的GraphQL API。

比特币开发相关链接: - c#比特币开发详解 - Java比特币开发详解 - PHP比特币开发详解 - 比特币数据分析工具 - 比特币PHP离线开发包 - Omni/USDT Java开发包

1、创建项目目录

在终端中执行如下命令创建一个新目录并进入该目录:

<code>mkdir btc-gql-api && cd btc-gql-api/<code>

2、初始化项目

在终端中执行yarn init初始化项目目录,得到的package.json类似以下内容:

<code>{  "name": "my-new-project",  "version": "1.0.0",  "description": "My New Project description.",  "main": "index.js",  "repository": {    "url": "https://example.com/your-username/my-new-project",    "type": "git"  },  "author": "Your Name ",  "license": "MIT"}/<code>

在终端执行touch index.js创建一个空的js文件,然后在package.json 中添加如下内容:

<code>..."scripts": {  "start": "node index.js"},.../<code>

最终的package.json文件看起来类似如下内容:

<code>{  "name": "my-new-project",  "version": "1.0.0",  "description": "My New Project description.",  "main": "index.js","scripts": {    "start": "node index.js"  },  "repository": {    "url": "https://example.com/your-username/my-new-project",    "type": "git"  },  "author": "Your Name ",  "license": "MIT"}/<code>

在项目目录中创建一个graph目录,得到如下的目录结构:

<code>+ btc-gql-api|__ graphql|__ package.json|__ index.json/<code>

在graph目录中创建3个js文件:types.js、resolver.js和request.js, 最终得到如下的目录结构:

<code>+ btc-gql-api|__+graphql|____request.js|____resolvers.js|____types.js|__ package.json|__ index.json/<code>

3、安装依赖包

在这个项目中,我们将需要axios和graphql-yoga,因此在项目根目录 执行如下命令:

<code>yarn add axios graphql-yoga/<code>

好了,可以开始写代码了。

4、类型定义

在GraphQL Schema中最基础的组件就是对象类型,它标识你可以从服务中提取的 对象类型,以及其中包含哪些字段。例如:

<code>type User {  name: String!  email: String!}/<code>

GraphQL有一些内置的基础类型:

  • Int:32位有符号整数
  • Float:双精度有符号浮点数
  • String:UTF-8字符序列
  • Boolean:布尔型,true或false
  • ID:唯一标识符,通常用于作为对象的键

更详细的文档可以参考graphql schema。

现在让我们定义类型。打开./graphql/types.js文件,输入如下内容:

<code>const typeDefs = `scalar JSONtype Price {  price:JSON!}`;module.exports = typeDefs;/<code>

在上面的代码中,我们定义了一个类型Price,它只有一个非空字段 price,字段类型为JSON:

<code>type Price {  price:JSON!}/<code>

JSON并不是graphql的内置类型,是我们自定义的:

<code>scalar JSON/<code>

5、查询

GraphQL是关于数据管理的,查询基本上就是请求对象的指定字段。 例如:

<code>query {  getPrices {    price  }}/<code>

得到如下结果:

<code>{  "data": {    "getPrices": {      "price": {        "USD": {          "15m": 10436.54,          "last": 10436.54,          "buy": 10436.54,          "sell": 10436.54,          "symbol": "$"        }        ...      }    }  }}/<code>

可以看到,查询结果和请求有相同的结构。

6、查询与修改

在一个schema内有两种类型:查询(query)与修改(mutation)。

每个GraphQL服务至少有一个查询类型,可能有一个修改类型。 这些类型和常规的对象类型一样,但是它们定义了每个GraphQL 查询的入口点。看起来像这样:

<code>scalar JSONtype Price {  price:JSON!}type Query {  getPrices: Price!  getPrice(currency:String!): Price!}/<code>

上面代码的意思是,我们的GraphQL服务有一个Query类型,其中包含 getPrices和getPrice字段,其类型都是Price。我们也可以看到字段 getPrice有参数(currency:String!)。在GraphQL对象类型中的每个 字段都可以有0或多个参数。

参数可以是必需的或可选的,在上面的例子中,我们要求一个必需的 参数currency用来选择要查询的币种。

7、请求辅助工具

在我们继续GraphQL之前,我们需要一个辅助工具来获取比特币实时价格。 为此我们将使用blockchain.com的API,但是你可以换成任何你喜欢的服务。

打开./graphql/request.js文件,输入以下内容:

<code>const axios = require("axios");module.exports = {  getPrices: async () => {    const url = "https://blockchain.info/ticker";    try {      return await axios.get(url);    } catch (error) {      console.error(error);    }  }};/<code>

上面的代码使用axios来构造GET请求,当然你也可以换成其他你熟悉的工具。

8、解析器

每个类型的每个字段背后都对应一个解析器函数,该函数应当由GraphQL 服务端开发者提供。当一个字段执行时,对应的解析器就被调用并生成结果。

如果一个字段生成一个标量值例如字符串或数字,那么执行就结束了。然而, 如果一个字段生成一个对象值,那么查询将包含另外的字段,这将继续解析 直到最终得到的字段都是标量值。

每个GraphQL服务的顶层是所有可能的入口类型,通常被称为根(Root)类型 或查询(Query)类型。

打开文件./graphql/resolvers.js,输入以下内容:

<code>const requests = require("./requests");const resolvers = {  Query: {    // Get all available prices    async getPrices(parent, args, ctx, info) {      const prices = await requests.getPrices();      return { price: prices.data };    },    // Get the price of a given currency symbol    async getPrice(parent, args, ctx, info) {      const prices = await requests.getPrices();      return { price: { [args["currency"]]: prices.data[args["currency"]] } };    }  }};module.exports = resolvers;/<code>

让我们分解说明下以上代码。

首先引入我们查询比特币实时行情的辅助工具:

<code>const request = require("./request");/<code>

然后定义解析器:

<code>const resolvers = {  Query: {    // Get all available prices    async getPrices(parent, args, ctx, info) {      const prices = await requests.getPrices();      return { price: prices.data };    },    // Get the price of a given currency symbol    async getPrice(parent, args, ctx, info) {      const prices = await requests.getPrices();      return { price: { [args["currency"]]: prices.data[args["currency"]] } };    }  }};/<code>

我们的解析器有一个根字段Query,在该对象内我们将定义GraphQL Schema中的所有 解析器。注意这些解析器的命名与types.js中一致。

每个解析器都是一个函数,有4个参数:

  • parent:父对象
  • args:参数
  • ctx:上下文
  • info:字段特定信息

9、服务器

现在我们已经有了类型、解析器和辅助工具,要做的就是整合起来。

打开index.js文件,输入以下内容:

<code>const { GraphQLServer } = require("graphql-yoga");const typeDefs = require("./graphql/types.js");const resolvers = require("./graphql/resolvers.js");const server = new GraphQLServer({  typeDefs,  resolvers,  context: {    //if we pass anything here can be available in all resolvers  }});server.start(() => console.log("Server is running on localhost:4000☄"));/<code>

首先我们创建GraphQLServer实例:

<code>...const server = new GraphQLServer({  typeDefs,  resolvers,  context: {    //if we pass anything here can be available in all resolvers  }});.../<code>

然后运行该实例:

<code>server.start(() => console.log("Server is running on localhost:4000☄"));/<code>

运行后可以看到如下输出:

<code>Server is running on localhost:4000☄/<code>

现在打开浏览器访问http://localhost:4000,测试如下查询:

<code>query($currency:String!){  getPrice(currency:$currency){    price  }}# Variables:{  "currency": "USD"}/<code>

得到如下结果:

实战比特币实时价格GraphQL API「Node.JS」

非常好!


原文链接:http://blog.hubwiz.com/2020/02/24/bitcoin-graphql-api/


分享到:


相關文章: