본문 바로가기
개발/Git, GitHub

깃허브 - RESTful API로 파일 읽기 (Read GitHub Files with GET)

by 피로물든딸기 2023. 6. 23.
반응형

깃허브 데스크탑으로 프로젝트 관리하기 강의 오픈!! (인프런 바로가기)

 

Git / GitHub 전체 링크

Node JS 전체 링크

 

참고

- 개인 토큰 발급 받기

 

- RESTful API로 파일의 SHA 구하기

- RESTful API로 파일 읽기

- RESTful API로 파일 쓰기

- RESTful API로 1MB 이상 큰 파일 읽기

- 깃허브 RESTful API로 파일 편집기 만들기

- https://docs.github.com/en/rest/repos/contents?apiVersion=2022-11-28 

- https://github.com/octokit/octokit.js#constructor-options

 

RESTful API를 이용해 GitHub에 존재하는 파일을 읽어보자.

개인 토큰 발급 받기를 참고하여 미리 토큰을 저장하자.


Node JS에서 파일 읽기

 

이제 아래 링크에 있는 파일을 읽어보자.

https://github.com/bloodstrawberry/auto-test

 

파일은 다음과 같다.

 

Node를 실행할 수 있는 환경에서 getApi.js 스크립트를 작성하고 실행해보자.

myKey에는 위에서 얻은 토큰을 넣어야 한다.

let myKey = "...";

const { Octokit } = require("@octokit/rest");

const octokit = new Octokit({
  auth: myKey
})

async function loginTest() {
  const {data : {login}} = await octokit.rest.users.getAuthenticated();
  console.log("Hello, %s", login);
}

loginTest();

 

토큰이 정상적으로 발급되었다면 아래의 로그가 출력된다.

 

GET 예제 링크를 참고하여 코드를 아래와 같이 수정하자.

let myKey = "...";

const { Octokit } = require("@octokit/rest");

const octokit = new Octokit({
  auth: myKey
})

async function test() {
  const result = await octokit.request('GET /repos/bloodstrawberry/auto-test/contents/test/apitest.txt', {
    owner: 'bloodstrawberry',
    repo: 'auto-test',
    path: 'test/apitest.txt',
    // API ver 지정 필요한 경우.
    // headers: { 
    //   'X-GitHub-Api-Version': '2022-11-28', 
    // }
  })

  console.log(result);
}

test();

 

참고로 기업에서 운영하는 사내 깃허브라면 baseUrl을 설정해야 한다. (링크 참고)

const octokit = new Octokit({
  auth: myKey,
  baseUrl: "https://github.your-company.com/api/v3"
})

 

node로 getApi.js를 실행하면 정상적으로 응답을 받을 수 있다.

PS D:\github\node-server\macro> node .\getApi.js
{
  status: 200,
  url: 'https://api.github.com/repos/bloodstrawberry/auto-test/contents/test/apitest.txt?owner=bloodstrawberry&repo=auto-test&path=test%2Fapitest.txt',
  headers: {
    'access-control-allow-origin': '*',
    'access-control-expose-headers': 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset',
    'cache-control': 'private, max-age=60, s-maxage=60',
    'content-encoding': 'gzip',
    'content-security-policy': "default-src 'none'",
    'content-type': 'application/json; charset=utf-8',
    date: 'Fri, 23 Jun 2023 11:08:29 GMT',
    etag: 'W/"38fee72bba1f743cddb306cc090e124c69030959"',
    'github-authentication-token-expiration': '2023-07-23 11:03:26 UTC',
    'last-modified': 'Fri, 23 Jun 2023 11:06:08 GMT',
    'referrer-policy': 'origin-when-cross-origin, strict-origin-when-cross-origin',
    server: 'GitHub.com',
    'strict-transport-security': 'max-age=31536000; includeSubdomains; preload',
    'transfer-encoding': 'chunked',
    vary: 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding, Accept, X-Requested-With',
    'x-accepted-oauth-scopes': '',
    'x-content-type-options': 'nosniff',
    'x-frame-options': 'deny',
    'x-github-api-version-selected': '2022-11-28',
    'x-github-media-type': 'github.v3; format=json',
    'x-github-request-id': '0AD0:7D0D:7EF70:8FB84:64957D2D',
    'x-oauth-scopes': 'repo',
    'x-ratelimit-limit': '5000',
    'x-ratelimit-remaining': '4993',
    'x-ratelimit-reset': '1687519765',
    'x-ratelimit-resource': 'core',
    'x-ratelimit-used': '7',
    'x-xss-protection': '0'
  },
  data: {
    name: 'apitest.txt',
    path: 'test/apitest.txt',
    sha: '38fee72bba1f743cddb306cc090e124c69030959',
    size: 19,
    url: 'https://api.github.com/repos/bloodstrawberry/auto-test/contents/test/apitest.txt?ref=main',
    html_url: 'https://github.com/bloodstrawberry/auto-test/blob/main/test/apitest.txt',
    git_url: 'https://api.github.com/repos/bloodstrawberry/auto-test/git/blobs/38fee72bba1f743cddb306cc090e124c69030959',
    download_url: 'https://raw.githubusercontent.com/bloodstrawberry/auto-test/main/test/apitest.txt',
    type: 'file',
    content: 'aGVsbG8sCmFwaXRlc3QhISEhCg==\n',
    encoding: 'base64',
    _links: {
      self: 'https://api.github.com/repos/bloodstrawberry/auto-test/contents/test/apitest.txt?ref=main',
      git: 'https://api.github.com/repos/bloodstrawberry/auto-test/git/blobs/38fee72bba1f743cddb306cc090e124c69030959',
      html: 'https://github.com/bloodstrawberry/auto-test/blob/main/test/apitest.txt'
    }
  }
}

 

파일 내용은 data.content에 포함되어 있으며 base64로 인코딩 되어 있다.

atob 메서드를 이용하면 base64 decode가 가능하다. (반대는 btoa)

로그를 확인해보면 정상적으로 RESTful API로 파일을 읽게 된다.

console.log(atob(result.data.content));

 

만약 파일 내용이 아니라 해당 경로의 파일 목록을 알고 싶다면 아래와 같이 API를 사용하면 된다.

async function test() {
  const result = await octokit.request('GET /repos/bloodstrawberry/auto-test/contents/test', {
    owner: 'bloodstrawberry',
  })

  console.log(result.data.map((item) => item.name));
}

 

위 API의 결과는 다음과 같다.

[ 'apitest.txt', 'cal.test.js', 'password.txt' ]

 

파일의 개수를 얻으려면 아래 방식을 사용할 수 있다.

result.data.filter(item => item.type === 'file').length;

 

실제 test 폴더에도 위의 파일이 존재하는 것을 알 수 있다.

반응형

댓글