API ( Application Programming Interface )
前言 :
API = 應用程式介面,關鍵字為介面( Interface )。為甚麼需要有介面 ? 因為我們是透過介面和他人進行溝通。舉例來說 : USB 其實是一個介面,電腦只需要依據這個介面去實作如何拿、存資料,製作 USB 隨身碟的廠商也只需要透過這套介面,去製作如何存取資料。所以,以 API 來說又可以分成 : 使用 API 、提供 API。
簡單地說,當我要和她人要東西時,可能無法直接要,這時就會透過她提供的 API 來和對方要東西;若我是提供資料的一方,也不希望對方直接存取我的資料庫,所以我會提供一個介面讓對方存取資料,在介面上取把控那些東西要給對方,那些東西不要。
http 只是一個協定,除了 http 外還有很多協定也在進行資料交換。
舉例 :
- 我要怎麼知道網路狀況 ? A : 作業系統有提供網路狀況的 API ,故我可以透過寫程式去呼叫作業系統提供的 API 去知道網路狀況。
我要怎麼讀取檔案 ? A : 作業系統有提供讀取檔案的 API , 故我可以透過寫程式去呼叫作業系統提供的 API 去讀取檔案。
所以,作業系統把控電腦大部分,作業系統提供甚麼 API 你就要用甚麼 API,作業系統扮演提供 API 角色。我要怎麼拿到FB好友資料 ? A : 我要串接臉書的 API ,我要先確認臉書的 API 有提供好友資料,不然我無法取得。
別人如何拿得我網站上的資訊 ? A : 我要提供 API 給他人,他人透過我提供的 API 就可以取得我網站上的資訊。
- 別人如何在我這新增資料 ? A : 我要提供給別人可以新增資料的 API ,別人可以透過我提供的 API 在我網站新增資訊。
結論
: 透過 API 可以讓雙方交換資料。
(一) API 與 Web API :
API 本質是交換資料,所以我可以與四面八方的人交換資料,如 : 作業系統,此外,提供者也不一定需要透過網路提供。串接 API 是指丟一個 req 你可以拿到 res。
- Web API : 通過網路提供 API ,通常提到 Web API 是指 HTTP API (透過 HTTP 協定的 API )
- SDK: 把東西都包裝好了,你只要用她就好了。
(二) 串接 HTTP API 實戰 ( get & post )
reqres.in,提供一系列可供測試的 API。
// 引入一個叫做 request 的 library
const request = require('request');
// 我發了一個 req 到這個網址去
request(
"https://reqres.in/api/users/",
function (error, response, body) {
console.log(body)
}
)
根據他的 API 格式,只要在後面加 /ID
就可以拿到這個 ID 的 USER 指標。印出的 response 資料格式是 string
const request = require('request');
request(
"https://reqres.in/api/users/2",
function (error, response, body) {
console.log(body)
}
)
API 串接結論 (1)
只要讀懂文件,發送 req 就 ok 了。
如果我希望 2 ,可以在打指令時呼叫,例如 : node api.js 2 可以抓到編號是 2 的 user ,我們可以怎麼做 ? 答 : 引入 const process = require('process')
,
const request = require('request');
const process = require('process')
console.log(process.argv) // 他是一個 arr
/* [
'C:\\Program Files\\nodejs\\node.exe',
'C:\\Users\\Liu\\desktop\\api.js'
]
第一個參數是 node
第二個參數是 api.js
第三個是我們所需要的參數
*/
const request = require('request');
const process = require('process')
request(
"https://reqres.in/api/users/"+process.argv[2], //也就是process.argv[2] 第三個元素
function (error, response, body) {
console.log(body)
}
)
也可以利用 post 來做 user 。於 api 文件 form
以下面範例而言,第一個參數是物件,裡面有你的 url 以及你用甚麼表單去接。
const request = require('request');
const process = require('process')
request.post(
{
url:'https://reqres.in/api/users',
form: {
name:'anna',
job : 'none'
}
},
function (error, response, body) {
console.log(body)
}
)
// {"name":"anna","job":"none","id":"154","createdAt":"2021-05-04T08:14:04.891Z"}
資料真的有寫成功嗎 ? 檢視真的有無拿到資料 ? 答 : 是空的,所以不是真的寫入,應該是假的 response。因為其目的是測試用,沒有寫入也沒關係。
const request = require('request');
const process = require('process')
request(
'https://reqres.in/api/users/154',
function (error, response, body) {
console.log(body)
}
)
// $ node api.js {}
(三) 串接 HTTP API 實戰 ( delete & patch )
我們可以在官方文件上看到不同的 method 。
檢視刪除狀況
const request = require('request');
request.delete(
'https://reqres.in/api/users/154',
function (error, response, body) {
console.log(response.statusCode)
}
)
// $ node api.js 204
const request = require('request');
request.patch(
{
url:'https://reqres.in/api/users/2',
form: {
name : 'hello'
}
},
function (error, response, body) {
console.log(response.statusCode)
console.log(body)
}
)
// 200
//{"name":"hello","updatedAt":"2021-05-04T08:25:39.878Z"}
HTTP API
(一) SOAP ( Simple Object Access Protocal) :
Protocal 是定義資料交換的格式,只要遵循 Protocal 的格式,就能輕易地進行資料交換。對 SOPA 而言,他的資料交換都透過 XML,使用上通常會藉由 Library 幫助,
(二) 非 SOAP :
大多數 API 都是這個樣子。發 req 到網址,然後回傳 jason 格式的資料,透過 http basic method and jason response 去溝通. 或是透過原本的表單、post 進行溝通。
(三) RESTful :
RESTful 不是協定,他是一個風格,不是必須遵循,只是一種 http 的風格建議。
舉例 : 刪除並非用 delete 而是用 post,但刪除用 delete 是良好習慣而非固定規範,事實上只要後端伺服器有處理刪除功能即可。不遵循風格建議可以,但有以下壞處(1) 不同工程師可能會有不同命名方式,容易造成混淆。(2) 語意不明確。
資料結構
無論在發送或接送資料,資料都有一定的格式。
(一) 純文字與自定義格式 :
respose 可以定義 : 狀態 : 良好 ;沒其他事
,但在處理 req 那端我必須有自己的規格去判斷 response 是甚麼。
if (response.body.indexOf (狀態 : 良好) {
......
}
結論
: 純文字的好處為可以自定義任何想要的格式,但壞處為需要相對應寫如何處理這些格式的函式。因此實務上以(二)、(三)為主流。
(二) XML ( Ex
tensible M
arkup L
anguage) :
與 HTML 神似,都是 mark up language (標記語言),利用標籤來標明屬性。
(三) JSON ( JavaScript Object Notation )
JSON是資料格式
而且非常無敵熱門。熱門理由 : (1) JSON 與 js 相容性高,因為他是基於 js 物件所產生的資料格式,長相類似 JS object (2) JSON 大小較 xml 小, xml 因為是標記語言,所以標籤佔據很多空間。JSON 只放必要資訊,所以佔據體積數比 xml 小。 (3) 其他程式語言也可以處理 JSON 格式的 library。實際上,任何一種資料格式,在任何程式語言都可以用。只要哪個語言有他的 parse,可以將它原本的資料格式轉為物件。
- JSON 規範 : key/ value 要用雙引號標起來
// 引入一個叫做 request 的 library
const request = require('request');
const process = require('process')
// 我發了一個 req 到這個網址去
request(
"https://reqres.in/api/users/"+process.argv[2],
function (error, response, body) {
console.log(body) // 回傳的是東西是 json 格式的物件,印出的東西是 str
}
)
/* {"data":{"id":2,"email":"janet.weaver@reqres.in","first_name":"Janet","last_name
":"Weaver","avatar":"https://reqres.in/img/faces/2-image.jpg"},"support":{"url":
"https://reqres.in/#support-heading","text":"To keep ReqRes free, contributions
towards server costs are appreciated!"}}
*/
因為 : 回傳的是東西是 json 格式的物件,印出的東西是 str , 所以直接寫console.log(body.data)
是不行的,我們可以用 JSON.parse()
,你後面傳進去的要是 JSON 格式的字串,所以 parse 完再印出的東西就會是 JS 的 object。此外,這時透過 console.log(json.data.email)
就可以把裡面東西印出來 = janet.weaver@reqres.in
// 引入一個叫做 request 的 library
const request = require('request');
const process = require('process')
// 我發了一個 req 到這個網址去
request(
"https://reqres.in/api/users/"+process.argv[2],
function (error, response, body) {
const json = JSON.parse(body)
console.log(json)
}
)
/*
{
data: {
id: 2,
email: 'janet.weaver@reqres.in',
first_name: 'Janet',
last_name: 'Weaver',
avatar: 'https://reqres.in/img/faces/2-image.jpg'
},
support: {
url: 'https://reqres.in/#support-heading',
text: 'To keep ReqRes free, contributions towards server costs are appreciat
ed!'
}
}
*/
我們也可以反其道而行,將 object 變成 JSON 格式的字串。JSON.stringify()
const obj = {
name : 'mike',
job : 'none'
}
//console.log(obj) { name: 'huli', job: 'none' }
console.log(JSON.stringify(obj)) // {"name":"mike","job":"none"}
簡易偵測指令-究竟哪個地方壞掉呢?
(一) curl :
基本上,任何網路的相關操作都可以透過 curl 搞定。
curl https://lidemy.com/courses/
相當於我發一個 get req 到該網址去,會返回他的 response 。下載資料
curl https://lidemy.com/courses/ > try.html
start try.html-I
我只要 headercurl local host
結論
: 可以用 curl 或是 node request 自己寫、 google 是你的好朋友
(二) nslookup :
可以解析出 domain 的 IP 位置是那些。比較 : ping
是測試你能否連到哪個地方,會不斷送封包,若雙方網路都沒問題一定 ping 的到。
(三) telnet : 要在 CML 使用
ping 一個指定的 port ,可以檢視指定的 port 是否有開。
telnet 52.74.223.119 7000
可以拿資料,例如 get / ,另外也可以傳資料。實際應用 : ppt 就是基於 telnet protocal。