在這篇文章中,我們将學習如何使用Node.js開發一個比特币實時價格行情的GraphQL API。
比特币開發相關連結:
1、建立項目目錄
在終端中執行如下指令建立一個新目錄并進入該目錄:
mkdir btc-gql-api && cd btc-gql-api
2、初始化項目
在終端中執行
yarn init
初始化項目目錄,得到的package.json類似以下内容:
{
"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 <[email protected]>",
"license": "MIT"
}
在終端執行
touch index.js
建立一個空的js檔案,然後在package.json中添加如下内容:
...
"scripts": {
"start": "node index.js"
},
...
最終的package.json檔案看起來類似如下内容:
{
"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 <[email protected]>",
"license": "MIT"
}
在項目目錄中建立一個graph目錄,得到如下的目錄結構:
+ btc-gql-api
|__ graphql
|__ package.json
|__ index.json
在graph目錄中建立3個js檔案:types.js、resolver.js和request.js,最終得到如下的目錄結構:
+ btc-gql-api
|__+graphql
|____request.js
|____resolvers.js
|____types.js
|__ package.json
|__ index.json
3、安裝依賴包
在這個項目中,我們将需要axios和graphql-yoga,是以在項目根目錄
執行如下指令:
yarn add axios graphql-yoga
好了,可以開始寫代碼了。
4、類型定義
在GraphQL Schema中最基礎的元件就是對象類型,它辨別你可以從服務中提取的對象類型,以及其中包含哪些字段。例如:
type User {
name: String!
email: String!
}
GraphQL有一些内置的基礎類型:
- Int:32位有符号整數
- Float:雙精度有符号浮點數
- String:UTF-8字元序列
- Boolean:布爾型,true或false
- ID:唯一辨別符,通常用于作為對象的鍵
更詳細的文檔可以參考
graphql schema。
現在讓我們定義類型。打開./graphql/types.js檔案,輸入如下内容:
const typeDefs = `
scalar JSON
type Price {
price:JSON!
}`;
module.exports = typeDefs;
在上面的代碼中,我們定義了一個類型Price,它隻有一個非空字段price,字段類型為JSON:
type Price {
price:JSON!
}
JSON并不是graphql的内置類型,是我們自定義的:
scalar JSON
5、查詢
GraphQL是關于資料管理的,查詢基本上就是請求對象的指定字段。
例如:
query {
getPrices {
price
}
}
得到如下結果:
{
"data": {
"getPrices": {
"price": {
"USD": {
"15m": 10436.54,
"last": 10436.54,
"buy": 10436.54,
"sell": 10436.54,
"symbol": "$"
}
...
}
}
}
}
可以看到,查詢結果和請求有相同的結構。
6、查詢與修改
在一個schema内有兩種類型:查詢(query)與修改(mutation)。
每個GraphQL服務至少有一個查詢類型,可能有一個修改類型。這些類型和正常的對象類型一樣,但是它們定義了每個GraphQL查詢的入口點。看起來像這樣:
scalar JSON
type Price {
price:JSON!
}
type Query {
getPrices: Price!
getPrice(currency:String!): Price!
}
上面代碼的意思是,我們的GraphQL服務有一個Query類型,其中包含
getPrices和getPrice字段,其類型都是Price。我們也可以看到字段
getPrice有參數
(currency:String!)
。在GraphQL對象類型中的每個
字段都可以有0或多個參數。
參數可以是必需的或可選的,在上面的例子中,我們要求一個必需的
參數currency用來選擇要查詢的币種。
7、請求輔助工具
在我們繼續GraphQL之前,我們需要一個輔助工具來擷取比特币實時價格。為此我們将使用blockchain.com的API,但是你可以換成任何你喜歡的服務。
打開./graphql/request.js檔案,輸入以下内容:
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);
}
}
};
上面的代碼使用axios來構造GET請求,當然你也可以換成其他你熟悉的工具。
8、解析器
每個類型的每個字段背後都對應一個解析器函數,該函數應當由GraphQL服務端開發者提供。當一個字段執行時,對應的解析器就被調用并生成結果。
如果一個字段生成一個标量值例如字元串或數字,那麼執行就結束了。然而,如果一個字段生成一個對象值,那麼查詢将包含另外的字段,這将繼續解析直到最終得到的字段都是标量值。
每個GraphQL服務的頂層是所有可能的入口類型,通常被稱為根(Root)類型或查詢(Query)類型。
打開檔案./graphql/resolvers.js,輸入以下内容:
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;
讓我們分解說明下以上代碼。
首先引入我們查詢比特币實時行情的輔助工具:
const request = require("./request");
然後定義解析器:
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"]] } };
}
}
};
我們的解析器有一個根字段Query,在該對象内我們将定義GraphQL Schema中的所有解析器。注意這些解析器的命名與types.js中一緻。
每個解析器都是一個函數,有4個參數:
- parent:父對象
- args:參數
- ctx:上下文
- info:字段特定資訊
9、伺服器
現在我們已經有了類型、解析器和輔助工具,要做的就是整合起來。
打開index.js檔案,輸入以下内容:
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☄"));
首先我們建立GraphQLServer執行個體:
...
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☄"));
運作後可以看到如下輸出:
Server is running on localhost:4000☄
現在打開浏覽器通路
http://localhost:4000,測試如下查詢:
query($currency:String!){
getPrice(currency:$currency){
price
}
}
# Variables:
{
"currency": "USD"
}

非常好!
原文連結:
用Node.jS開發比特币行情GraphQL API — 彙智網