コード
古い issue の一覧をチャットに通知するツールを作成しておりまして、その一環として書いたコードです。
組織(ユーザー)名、リポジトリ名はクエリパラメータに設定するなど複数パターンがあるようですが、今回は下記URLでアクセスしました。
[GET] https://api.github.com/orgs/{org}/issues
コードは下記の通りです。
importfetchfrom'isomorphic-unfetch';import{Issue,State}from'./types/vendor';exportasyncfunctionget_issues(owner:string,repository:string,api_token:string,state:State// `State`の方は`'open' | 'closed' | 'all'`です。):Promise<Issue[]>{constresponse=awaitfetch(`https://api.github.com/repos/${owner}/${repository}/issues`+`?state=${state}`,{headers:{Authorization:`token ${api_token}`,Accept:'application/vnd.github.v3+json',},});if(response.status!=200){thrownewError(`GitHub API にアクセスできませんでした: ${JSON.stringify(awaitresponse.json(),null,'')}`);}return(awaitresponse.json())asIssue[];}
Node.js 環境でも ブラウザ環境でも動くfetchを使用するためにisomorphic-unfetch
を使用しています。
# yarn の場合$ yarn add isomorphic-unfetch
# npm の場合$ npm install isomorphic-unfetch
Issue
の型は QuickType でinterface
自動生成してtype
に差し替えました。
型の詳しい内容は下記の実際のソースをご確認ください。
https://github.com/sugu-sano/notify-old-issues/blob/master/src/types/vendor/isssue.ts
今回は不要でしたので設定しませんでしたが、クエリパラメータにはsort
(並び順)、since
(指定された時間以降に更新された)もありました。詳しくは下記公式ドキュメントを参照ください。
List repository issues - GitHub Docs
https://docs.github.com/en/free-pro-team@latest/rest/reference/issues#list-repository-issues
Octkit という GitHub 公式の REST クライアントが存在した
生のfetch API
でアクセスしていましたが GitHub にはOctokit
という公式クライアントがありました。
また型定義も提供されていてパラメータやレスポンスの型は自作しなくてもタイプセーフに扱うことができます。
# yarn の場合$ yarn add @octokit/core @octokit/types
# npm の場合$ npm install @octokit/core @octokit/types
import{Octokit}from"@octokit/core";import{Endpoints}from"@octokit/types";asyncfunctionmain(){// 型の取得の仕方に若干クセがあるtyperoute="GET /repos/:owner/:repo/issues";typeResponse=Endpoints[route]["response"];typeParameters=Endpoints[route]["parameters"];constparams:Parameters={owner:"octocat",repo:"hello-world",since:"2020-11-20T00:00:00",};constoctokit=newOctokit();// 戻り値が `OctokitResponse<any>` にならないように型注釈constresponse:Response=awaitoctokit.request("GET /repos/{owner}/{repo}/issues",params);console.log(response.data);// `any` でなく `IssuesListForRepoResponseData` 型になる}main();
実行すると下記レスポンスが確認できました。
レスポンス(長いので折りたたみ)
[{url:'https://api.github.com/repos/octocat/Hello-World/issues/812',repository_url:'https://api.github.com/repos/octocat/Hello-World',labels_url:'https://api.github.com/repos/octocat/Hello-World/issues/812/labels{/name}',comments_url:'https://api.github.com/repos/octocat/Hello-World/issues/812/comments',events_url:'https://api.github.com/repos/octocat/Hello-World/issues/812/events',html_url:'https://github.com/octocat/Hello-World/issues/812',id:748885338,node_id:'MDU6SXNzdWU3NDg4ODUzMzg=',number:812,title:'Test title',user:{login:'avihlbi',id:54238151,node_id:'MDQ6VXNlcjU0MjM4MTUx',avatar_url:'https://avatars0.githubusercontent.com/u/54238151?v=4',gravatar_id:'',url:'https://api.github.com/users/avihlbi',html_url:'https://github.com/avihlbi',followers_url:'https://api.github.com/users/avihlbi/followers',following_url:'https://api.github.com/users/avihlbi/following{/other_user}',gists_url:'https://api.github.com/users/avihlbi/gists{/gist_id}',starred_url:'https://api.github.com/users/avihlbi/starred{/owner}{/repo}',subscriptions_url:'https://api.github.com/users/avihlbi/subscriptions',organizations_url:'https://api.github.com/users/avihlbi/orgs',repos_url:'https://api.github.com/users/avihlbi/repos',events_url:'https://api.github.com/users/avihlbi/events{/privacy}',received_events_url:'https://api.github.com/users/avihlbi/received_events',type:'User',site_admin:false},labels:[],state:'open',locked:false,assignee:null,assignees:[],milestone:null,comments:1,created_at:'2020-11-23T15:13:32Z',updated_at:'2020-11-23T15:13:33Z',closed_at:null,author_association:'NONE',active_lock_reason:null,body:'Test description',performed_via_github_app:null},{url:'https://api.github.com/repos/octocat/Hello-World/issues/810',repository_url:'https://api.github.com/repos/octocat/Hello-World',labels_url:'https://api.github.com/repos/octocat/Hello-World/issues/810/labels{/name}',comments_url:'https://api.github.com/repos/octocat/Hello-World/issues/810/comments',events_url:'https://api.github.com/repos/octocat/Hello-World/issues/810/events',html_url:'https://github.com/octocat/Hello-World/pull/810',id:747843269,node_id:'MDExOlB1bGxSZXF1ZXN0NTI0OTkzMTY0',number:810,title:'Test PR for Codespaces',user:{login:'2percentsilk',id:3174849,node_id:'MDQ6VXNlcjMxNzQ4NDk=',avatar_url:'https://avatars3.githubusercontent.com/u/3174849?v=4',gravatar_id:'',url:'https://api.github.com/users/2percentsilk',html_url:'https://github.com/2percentsilk',followers_url:'https://api.github.com/users/2percentsilk/followers',following_url:'https://api.github.com/users/2percentsilk/following{/other_user}',gists_url:'https://api.github.com/users/2percentsilk/gists{/gist_id}',starred_url:'https://api.github.com/users/2percentsilk/starred{/owner}{/repo}',subscriptions_url:'https://api.github.com/users/2percentsilk/subscriptions',organizations_url:'https://api.github.com/users/2percentsilk/orgs',repos_url:'https://api.github.com/users/2percentsilk/repos',events_url:'https://api.github.com/users/2percentsilk/events{/privacy}',received_events_url:'https://api.github.com/users/2percentsilk/received_events',type:'User',site_admin:false},labels:[],state:'open',locked:false,assignee:null,assignees:[],milestone:null,comments:0,created_at:'2020-11-20T22:48:47Z',updated_at:'2020-11-20T22:48:47Z',closed_at:null,author_association:'NONE',active_lock_reason:null,pull_request:{url:'https://api.github.com/repos/octocat/Hello-World/pulls/810',html_url:'https://github.com/octocat/Hello-World/pull/810',diff_url:'https://github.com/octocat/Hello-World/pull/810.diff',patch_url:'https://github.com/octocat/Hello-World/pull/810.patch'},body:'',performed_via_github_app:null},{url:'https://api.github.com/repos/octocat/Hello-World/issues/808',repository_url:'https://api.github.com/repos/octocat/Hello-World',labels_url:'https://api.github.com/repos/octocat/Hello-World/issues/808/labels{/name}',comments_url:'https://api.github.com/repos/octocat/Hello-World/issues/808/comments',events_url:'https://api.github.com/repos/octocat/Hello-World/issues/808/events',html_url:'https://github.com/octocat/Hello-World/issues/808',id:744550518,node_id:'MDU6SXNzdWU3NDQ1NTA1MTg=',number:808,title:'Click Here',user:{login:'irfaardy',id:49023326,node_id:'MDQ6VXNlcjQ5MDIzMzI2',avatar_url:'https://avatars1.githubusercontent.com/u/49023326?v=4',gravatar_id:'',url:'https://api.github.com/users/irfaardy',html_url:'https://github.com/irfaardy',followers_url:'https://api.github.com/users/irfaardy/followers',following_url:'https://api.github.com/users/irfaardy/following{/other_user}',gists_url:'https://api.github.com/users/irfaardy/gists{/gist_id}',starred_url:'https://api.github.com/users/irfaardy/starred{/owner}{/repo}',subscriptions_url:'https://api.github.com/users/irfaardy/subscriptions',organizations_url:'https://api.github.com/users/irfaardy/orgs',repos_url:'https://api.github.com/users/irfaardy/repos',events_url:'https://api.github.com/users/irfaardy/events{/privacy}',received_events_url:'https://api.github.com/users/irfaardy/received_events',type:'User',site_admin:false},labels:[],state:'open',locked:false,assignee:null,assignees:[],milestone:null,comments:1,created_at:'2020-11-17T09:09:54Z',updated_at:'2020-11-23T09:43:57Z',closed_at:null,author_association:'NONE',active_lock_reason:null,body:'I love you\r\n\r\n----\r\n[Click Here](https://github.com/irfaardy)',performed_via_github_app:null},{url:'https://api.github.com/repos/octocat/Hello-World/issues/576',repository_url:'https://api.github.com/repos/octocat/Hello-World',labels_url:'https://api.github.com/repos/octocat/Hello-World/issues/576/labels{/name}',comments_url:'https://api.github.com/repos/octocat/Hello-World/issues/576/comments',events_url:'https://api.github.com/repos/octocat/Hello-World/issues/576/events',html_url:'https://github.com/octocat/Hello-World/pull/576',id:515476262,node_id:'MDExOlB1bGxSZXF1ZXN0MzM0OTMzMjIy',number:576,title:'Update README',user:{login:'NX007KTR',id:41190306,node_id:'MDQ6VXNlcjQxMTkwMzA2',avatar_url:'https://avatars3.githubusercontent.com/u/41190306?v=4',gravatar_id:'',url:'https://api.github.com/users/NX007KTR',html_url:'https://github.com/NX007KTR',followers_url:'https://api.github.com/users/NX007KTR/followers',following_url:'https://api.github.com/users/NX007KTR/following{/other_user}',gists_url:'https://api.github.com/users/NX007KTR/gists{/gist_id}',starred_url:'https://api.github.com/users/NX007KTR/starred{/owner}{/repo}',subscriptions_url:'https://api.github.com/users/NX007KTR/subscriptions',organizations_url:'https://api.github.com/users/NX007KTR/orgs',repos_url:'https://api.github.com/users/NX007KTR/repos',events_url:'https://api.github.com/users/NX007KTR/events{/privacy}',received_events_url:'https://api.github.com/users/NX007KTR/received_events',type:'User',site_admin:false},labels:[],state:'open',locked:false,assignee:null,assignees:[],milestone:null,comments:1,created_at:'2019-10-31T14:26:43Z',updated_at:'2020-11-29T05:03:18Z',closed_at:null,author_association:'NONE',active_lock_reason:null,pull_request:{url:'https://api.github.com/repos/octocat/Hello-World/pulls/576',html_url:'https://github.com/octocat/Hello-World/pull/576',diff_url:'https://github.com/octocat/Hello-World/pull/576.diff',patch_url:'https://github.com/octocat/Hello-World/pull/576.patch'},body:'',performed_via_github_app:null}]