鍍金池/ 教程/ Java/ 準備開始
集成自動化部署
架設 CI 服務器
探索用戶資源
SSH agent 轉發(fā)
使用評論
身份認證基礎
管理部署密鑰
準備開始
傳遞部署
遍歷分頁
整合者的最佳做法
數據渲染成圖表

準備開始

讓我們來通過一些核心的 API 概念為我們處理一些日常用例。

概述

大部分應用都會使用你選擇的語言的一個現有 封裝好的庫,但是先熟悉內部的 API HTTP 方法是很重要的。

通過 cURL 來進行試驗是最簡單的。

Hello World

首先,我們來測試我們的設置是否正確。打開一個命令提示符,輸入下面的命令(不需要 $ 符號)

    $ curl https://api.github.com/zen

    Keep it logically awesome.

返回的內容將會是我們的設計理念中隨機抽取的一條。

接下來,我們向 Chris Wanstrath's GitHub profile 發(fā)送一個 GET 請求:

    # GET /users/defunkt
    $ curl https://api.github.com/users/defunkt

    {
      "login": "defunkt",
      "id": 2,
      "url": "https://api.github.com/users/defunkt",
      "html_url": "https://github.com/defunkt",
      ...
    }

Mmmmm,這看起來像 JSON。讓我們添加 -i 參數來包含頭部信息。

    $ curl -i https://api.github.com/users/defunkt

    HTTP/1.1 200 OK
    Server: GitHub.com
    Date: Sun, 11 Nov 2012 18:43:28 GMT
    Content-Type: application/json; charset=utf-8
    Connection: keep-alive
    Status: 200 OK
    ETag: "bfd85cbf23ac0b0c8a29bee02e7117c6"
    X-RateLimit-Limit: 60
    X-RateLimit-Remaining: 57
    X-RateLimit-Reset: 1352660008
    X-GitHub-Media-Type: github.v3
    Vary: Accept
    Cache-Control: public, max-age=60, s-maxage=60
    X-Content-Type-Options: nosniff
    Content-Length: 692
    Last-Modified: Tue, 30 Oct 2012 18:58:42 GMT

    {
      "login": "defunkt",
      "id": 2,
      "url": "https://api.github.com/users/defunkt",
      "html_url": "https://github.com/defunkt",
      ...
    }

在返回的頭部信息中有一些有趣的數據。如預期那樣,Content-Type 屬性的值是 application/json

每一個以 X- 開頭的頭部都是自定義頭,它們都不包含于 HTTP 標準。讓我們看看其中的幾個:

  • x-GitHub-Media-Type 的值為 github.v3。這告訴我們返回值的媒體類型。媒體類型幫助在 API v3 中確定我們的輸出的版本信息。我們將在后面更深入探討。

  • 注意 X-RateLimit-LimitX-RateLimit-Remaining headers。這一對頭部信息標示出了在一個滾動時間周期內(一般是一個小時)一個客戶端能夠發(fā)起多少請求和這些請求多少已經完成。

身份認證

沒認證的客戶端每小時可以制造60個請求。如果想制造更多,我們需要進行認證。實際上,使用 GitHub API 做任何有趣一點的事情都會要求認證。

基礎

GitHub API 最簡單的認證方式是使用你的 GitHub 用戶名和密碼來通過基礎認證。

    $ curl -i -u <your_username> https://api.github.com/users/defunkt

    Enter host password for user '<your_username>':

這個 -u 參數設置用戶名,cURL 會提示你填寫密碼。你可以使用 -u "username:password" 來避免這個提醒,但這會使你的密碼被記錄在 shell 的歷史記錄中,所以并不推薦這種做法。驗證時,你會看到你的速度限制會升到每小時 5000 個請求,這個會在 X-RateLimit-Limit 頭部信息中標示。

雙重認證

如果你啟用了雙重認證,這個 API 會在以上請求中返回 401 Unauthorized 錯誤碼(其他的 API 請求也一樣):

    $ curl -i -u <your_username> https://api.github.com/users/defunkt

    Enter host password for user '<your_username>':

    HTTP/1.1 401 Unauthorized
    X-GitHub-OTP: required; :2fa-type

    {
      "message": "Must specify two-factor authentication OTP code.",
      "documentation_url": "https://developer.github.com/v3/auth#working-with-two-factor-authentication"
    }

避免這個錯誤最簡單的方式是創(chuàng)建一個 OAuth 令牌和使用 OAuth 認證,而不是使用簡單的基礎認證。在下面的 OAuth 部分可以看到更詳細的信息。

獲取自己配置文件

當認證通過時,你可以利用與 GitHub 賬戶相關聯的權限。例如,嘗試獲取你的用戶配置文件:

    $ curl -i -u <your_username> https://api.github.com/user

    {
      ...
      "plan": {
        "space": 2516582,
        "collaborators": 10,
        "private_repos": 20,
        "name": "medium"
      }
      ...
    }

這一次,除了和早先我們獲取 @defunkt 同樣的公共信息集合外,你還將看到你自己用戶配置的非公共信息。比如,你將在返回值看到一個 plan 對象,它給出了賬戶的 GitHub 計劃的細節(jié)。

OAuth

基本認證雖然方便,但是并不理想,因為你不應該將你的 GitHub 用戶名和密碼共享給任何人。需要通過 API 讀寫另一個用戶的私有信息時必須使用 OAuth。

OAuth 用令牌(token)替代了用戶名和密碼。令牌有兩大特色:

  • 可撤銷訪問:用戶能夠在任何時候撤銷對第三方 app 的認證。
  • 有限訪問:用戶能夠在授權一個第三方 app 之前檢驗特定的準入權限。

一般來說,令牌能夠通過一個 web 流 來創(chuàng)建。一個應用將用戶跳轉到 Github 登陸。然后 GitHub 會顯示對話框來標明應用的名字,同時也顯示應用曾經被授予的用戶權限。當用戶授權之后,GitHub 會將用戶重定向跳轉回應用:

http://wiki.jikexueyuan.com/project/github-developer-guides/images/oauth_prompt.png" alt="" />

然而,開始使用 OAuth 令牌并不需要你配置整個 web 流。獲取一個令牌的簡單方法是通過個人準入令牌設置頁 創(chuàng)建一個個人準入令牌:

http://wiki.jikexueyuan.com/project/github-developer-guides/images/personal_token.png" alt="" />

同時,授權 API 使得通過基本授權創(chuàng)建一個 OAuth 令牌變得簡單。試試粘貼并運行以下命令:

    $ curl -i -u <your_username> -d '{"scopes": ["repo", "user"], "note": "getting-started"}' \
    https://api.github.com/authorizations

    HTTP/1.1 201 Created
    Location: https://api.github.com/authorizations/2
    Content-Length: 384

    {
      "scopes": [
        "repo",
        "user"
      ],
      "token": "5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4",
      "updated_at": "2012-11-14T14:04:24Z",
      "url": "https://api.github.com/authorizations/2",
      "app": {
        "url": "https://developer.github.com/v3/oauth/#oauth-authorizations-api",
        "name": "GitHub API"
      },
      "created_at": "2012-11-14T14:04:24Z",
      "note_url": null,
      "id": 2,
      "note": "getting-started"
    }

這個小調用里面包含了很多過程,讓我們來分解一下。首先,-d 標志表明我們正在做一個 POST 調用,使用的是 application/x-www-form-urlencoded內容類型(和 GET 相對)。所有對 GitHub API 發(fā)起的 POST 請求都必須用 JSON 編寫。

接下來,讓我們看看我們在這個請求播送的 scopes 字段。當創(chuàng)建一個新的令牌時,我們包含了一個可選的數組 scopes,或用來標示這個令牌能夠獲取的信息的準入等級。在這個例子中,我們設置該令牌擁有 repo 權限,這個權限將授予用戶讀寫公共和私有倉庫的權限;該令牌還有 user 域權限,這將授予用戶讀寫公共和私有用戶簡介數據。查看 區(qū)域文檔可以獲得所有區(qū)域的列表。為了避免因可能的侵入行為嚇到用戶,你應該只請求你的應用所實際需要的權限。 201 的狀態(tài)碼告訴我們調用是成功的,并且返回的 JSON 包含了新 OAuth 令牌的詳細信息。

如果你已經打開雙重授權,API 將對上述請求返回前面所述的 401 Unauthorize 錯誤碼。你能夠通過在 X-GitHub-OTP 請求頭 包含一個 2FA OTP 碼來回避這個錯誤:

    $ curl -i -u <your_username> -H "X-GitHub-OTP: <your_2fa_OTP_code>" \
        -d '{"scopes": ["repo", "user"], "note": "getting-started"}' \
        https://api.github.com/authorizations

如果你在一個移動應用打開了 2FA ,可以通過你的手機的一次性密碼獲取一個 OTP 碼。如果你通過短信打開了 2FA,發(fā)起此請求后,你將受到一條包含你的 OTP 碼的短信。

現在,我們能夠在剩下的例子中使用這個40字節(jié)的令牌來替代用戶名和密碼。讓我們再次獲取我們的個人信息,這一次我們使用 OAuth:

    $ curl -i -H 'Authorization: token 5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4' \
        https://api.github.com/user

請向對待密碼一樣對待 OAuth 令牌!不要和其他用戶分享令牌或者將令牌存儲在不安全的地方。這些例子中的令牌是偽造的,名字也已經修改過,以免影響無關用戶。

現在我們知道了如何進行授權請求,接下來我們來看Repositories API

Repositories

幾乎所有有意義的 GitHub API 使用會包含了某種程度的 repositories 信息。我們能夠像我們前面獲取用戶詳細信息一樣獲取 repository 詳情:

    $ curl -i https://api.github.com/repos/twbs/bootstrap

用同樣的方式,我們能夠為授權用戶查看 repositories

    $ curl -i -H 'Authorization: token 5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4' \
        https://api.github.com/user/repos

或者我們能夠查看另一個用戶的 repositories

    $ curl -i https://api.github.com/users/technoweenie/repos

或者,我們能夠查看一個組織的 repositories

    $ curl -i https://api.github.com/orgs/mozilla/repos

這些調用返回的信息將依賴于我們怎樣被授權的:

  • 使用基本授權,返回將包含所有用戶在 github.com 能夠查看的 repositories。
  • 使用 OAuth 的話,如果 OAuth 令牌包含了 repo 域,則將只返回私有 repositories。

就像文檔中指出的一樣,這些方法包含了一個 type 參數以便根據用戶對 repository 擁有的訪問權限類型來過濾返回的 repositories。通過這種方式,我們能夠單獨獲取直接擁有的 repositories,組織的 repositories,或者用戶通過一個小組合作的 repositories。

    $ curl -i "https://api.github.com/users/technoweenie/repos?type=owner"

在這個例子中,我們獲取了 technoweenie 用戶擁有的 repositories,而不是那些他正在和其他人合作的 repositories。注意上面被引號包括的 URL。依賴于你的 shell 設置, cURL 有時候會要求 URL 被引號包括,否則將忽略查詢字符串。

創(chuàng)建一個 repository

獲取一個已存在的 repository 的信息是非常常見的應用,但是 GitHub API 也支持創(chuàng)建新的 repositories。為了 創(chuàng)建一個 repository ,我們需要 POST 一些包含細節(jié)和配置選項的 JSON :

    $ curl -i -H 'Authorization: token 5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4' \
        -d '{ \
            "name": "blog", \
            "auto_init": true, \
            "private": true, \
            "gitignore_template": "nanoc" \
        }' \
        https://api.github.com/user/repos

在這里最小例子里面,我們?yōu)槲覀兊牟┛停赡苁羌茉O在 GitHub Pages )創(chuàng)建了一個新的 repository。 雖然博客將會是公共的,但是我們將 repository 設置為私有的。同樣,在這個請求里,我們用一個 README 文件和一個 nanoc-flavored .gitignore 模板初始化這個 repository。

創(chuàng)建的 repository 將可以在 https://github.com/<your_username>/blog 找到。要創(chuàng)建一個你擁有的組織下的 repository,僅需要修改一個 API 方法,將 /user/repos 變更為 /orgs/<org_name>/repos

接下來,讓我們獲取我們新創(chuàng)建的 repository :

    $ curl -i https://api.github.com/repos/pengwynn/blog

    HTTP/1.1 404 Not Found

    {
        "message": "Not Found"
    }

這是怎么一回事?返回了一個 404 錯誤。因為我們將 repository 設置為私有的,我們需要授權才能查看它。如果你是一個 HTTP 的老用戶,你可能會期望一個 403 而不是 404。但是因為我們不想泄露私有 repositories 的任何信息,所以 GitHub API 在這種情況下返回一個 404,表示我們不能確定或者否認這個 repository 的存在。

Issues

GitHub Issues UI 目標在于當你遠離你的方向的時候給你提供適合的工作流。通過 GitHub Issues API,你可以使用其他工具提取數據或者創(chuàng)建 Issues 來給你的團隊創(chuàng)建一個工作流。

就像 github.com, 這個 API 給認證用戶提供了一些查看 issues 的方法。查看你的全部 issues,使用 GET/issues:

    $ curl -i -H 'Authorization: token 5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4' \
    https://api.github.com/issues

想要獲取你其中一個組織下的 issues,使用 GET /orgs/<org>/issues:

    $ curl -i -H 'Authorization: token 5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4' \
    https://api.github.com/orgs/rails/issues

我們也可以獲取單一 repository 中的全部 issues

    $ curl -i https://api.github.com/repos/rails/rails/issues

分頁

一個項目的 Rails 大小擁有上千個 issues。我們將需要進行分頁處理,使用多種 API 來獲取數據。重復最后一條命令,這時候需要注意回復的 headers:

    $ curl -i https://api.github.com/repos/rails/rails/issues

    HTTP/1.1 200 OK

    Link: <https://api.github.com/repos/rails/rails/issues?page=2>; rel="next",
    <https://api.github.com/repos/rails/rails/issues?page=14>; rel="last"

Link頭部信息將提供一個方法來響應鏈接外部資源,用這種方式來獲取額外頁面的數據。當我們請求獲取超過30條(默認的頁面大?。﹊ssues 的時候,這個 API 將會告訴我們哪里可以獲取下一頁和最后一頁的結果。

創(chuàng)建一個 issue

我們已經知道怎么將 issues 分頁,現在讓我們使用 API 來創(chuàng)建一個 issue。

要創(chuàng)建一個 issue,我們需要先通過認證,所以在請求的頭部需要傳遞 OAuth 令牌。同時,我們需要傳遞 JSON body 中的 title,body 和 labels 到我們想要創(chuàng)建 issue 的 repository 下面的 /issues 路徑:

    $ curl -i -H 'Authorization: token 5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4' \
    -d '{ \
         "title": "New logo", \
         "body": "We should have one", \
         "labels": ["design"] \
       }' \
    https://api.github.com/repos/pengwynn/api-sandbox/issues

    HTTP/1.1 201 Created
    Location: https://api.github.com/repos/pengwynn/api-sandbox/issues/17
    X-RateLimit-Limit: 5000

    {
      "pull_request": {
        "patch_url": null,
        "html_url": null,
        "diff_url": null
      },
      "created_at": "2012-11-14T15:25:33Z",
      "comments": 0,
      "milestone": null,
      "title": "New logo",
      "body": "We should have one",
      "user": {
        "login": "pengwynn",
        "gravatar_id": "7e19cd5486b5d6dc1ef90e671ba52ae0",
        "avatar_url": "https://secure.gravatar.com/avatar/7e19cd5486b5d6dc1ef90e671ba52ae0?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png",
        "id": 865,
        "url": "https://api.github.com/users/pengwynn"
      },
      "closed_at": null,
      "updated_at": "2012-11-14T15:25:33Z",
      "number": 17,
      "closed_by": null,
      "html_url": "https://github.com/pengwynn/api-sandbox/issues/17",
      "labels": [
        {
          "color": "ededed",
          "name": "design",
          "url": "https://api.github.com/repos/pengwynn/api-sandbox/labels/design"
        }
      ],
      "id": 8356941,
      "assignee": null,
      "state": "open",
      "url": "https://api.github.com/repos/pengwynn/api-sandbox/issues/17"
    }

這個 response 給我們回復了新創(chuàng)建 issue 的一系列指針(pointers),有響應頭的位置還有 JSON response 的url 域。

條件請求

作為一個好的api用戶很重要的一點就是緩存信息(從來不改變的)以配合api的速度限制。這個 API 提供條件請求和幫你做正確的事。試想一下我們用來獲取 defunkt’s 配置的第一條命令:

    $ curl -i https://api.github.com/users/defunkt

    HTTP/1.1 200 OK
    ETag: "bfd85cbf23ac0b0c8a29bee02e7117c6"

除了 JSON body,我們注意 HTTP 的狀態(tài)碼200和 ETag 的頭部信息。ETag是 response 的“指紋”。如果我們在隨后的訪問中傳遞它,我們就可以告訴 API 讓它再一次回復之前的 resource,前提是它已經發(fā)生改變。

    $ curl -i -H 'If-None-Match: "bfd85cbf23ac0b0c8a29bee02e7117c6"' \
    https://api.github.com/users/defunkt

    HTTP/1.1 304 Not Modified

狀態(tài)碼304表明這個資源在我們之前訪問到現在時間內都沒有發(fā)生改變,并且這個 response 將不包含 body。作為獎勵,這個304響應將不會影響你的速率限制。

喔!現在我們知道了 GitHub API 的基礎。

  • 基礎 & OAuth 認證
  • Fetching 和 創(chuàng)建 repositories 和 issues
  • 條件請求

繼續(xù)學習下一個 API 指南 身份認證基礎 !

上一篇:遍歷分頁下一篇:架設 CI 服務器