Lompat ke konten
dokumentasi.id
Commit d59d965
v3
Star763

5.1

Pengumpulan Data Profil GitHub

Endpoint tidak mengirim URL profil ke model. Ia lebih dulu merakit satu objek datas dari tiga permintaan keluar: profil pengguna, daftar repository, dan README profil, lalu menyerialisasikannya ke dalam prompt. Pemeriksaan cache D1 yang berjalan sebelum pengumpulan data dibahas di Endpoint POST /llama, sedangkan pemakaian datas sebagai prompt dibahas di Prompt Multibahasa.

Ketiga permintaan memakai satu objek headers di level modul: Accept: 'application/json', Content-Type: 'application/json', dan User-Agent: 'github-roast.pages.dev' (src/routes/llama/+server.js:9-13). Bila GITHUB_API_KEY terisi, satu kunci Authorization ditambahkan dengan format token ${GITHUB_API_KEY} (src/routes/llama/+server.js:49-51).

Urutan Pengambilan Data

sequenceDiagram
  autonumber
  participant C as Client
  participant S as "POST /llama"
  participant DB as "D1 roasts"
  participant GH as "api.github.com"
  participant RAW as "raw.githubusercontent.com"

  C->>S: username dan language
  S->>DB: SELECT roasts WHERE gh_username dan language
  alt cache hit
    DB-->>S: history
    S-->>C: roast lama, tanpa panggilan GitHub
  else cache miss
    S->>S: tambahkan Authorization bila GITHUB_API_KEY ada
    S->>GH: GET /users/username
    alt response.ok
      GH-->>S: profileResponse
      S->>S: useToken = true
    else response tidak ok
      S-->>C: 500 Our roast machine is in trouble
    end
    Note over S,GH: bila fetch melempar error, permintaan profil diulang sekali
    S->>S: hapus Authorization bila useToken == false
    S->>GH: GET /users/username/repos sort=updated
    GH-->>S: repoResponse
    S->>RAW: GET /username/username/main/README.md
    alt response.ok
      RAW-->>S: readmeResponse
    else fetch melempar error
      S->>RAW: GET /username/username/master/README.md
      RAW-->>S: readmeResponse
    end
    S->>S: susun datas untuk prompt
  end
%% fig: Siklus pengumpulan data profil GitHub
%% desc: Setelah cache D1 meleset, endpoint mengambil profil, daftar repository, dan README profil, masing-masing dengan jalur cadangan sendiri.
Fig. 1: Siklus pengumpulan data profil GitHubSetelah cache D1 meleset, endpoint mengambil profil, daftar repository, dan README profil, masing-masing dengan jalur cadangan sendiri.

Langkah pertama mengumpulkan profil. profileResponse disiapkan dengan nilai awal { status: 403 } dan useToken disetel false, lalu fetch memanggil https://api.github.com/users/${username} dengan { headers } (src/routes/llama/+server.js:53-71). Bila respons ok, hasil response.json() disimpan di profileResponse dan useToken menjadi true. Bila respons tidak ok, handler langsung mengembalikan json({ error: 'Our roast machine is in trouble' }, { status: 500 }) tanpa mencoba jalur lain.

Jalur cadangan hanya aktif saat fetch melempar error. Blok catch mencetak error lewat console.log(err), mengulang permintaan yang sama, dan menimpa profileResponse dengan hasil percobaan kedua (src/routes/llama/+server.js:53-71). Karena useToken tetap false pada jalur ini, kunci Authorization dihapus dari objek headers (src/routes/llama/+server.js:74-76). Dua permintaan setelahnya berjalan tanpa token.

Daftar Repository

Permintaan kedua mengambil https://api.github.com/users/${username}/repos?sort=updated dengan headers yang sudah disesuaikan (src/routes/llama/+server.js:78-81). Tidak ada parameter per_page; pemotongan jumlah dilakukan di sisi aplikasi. Hasil response.json() disimpan sebagai repoResponse tanpa pemeriksaan response.ok.

README Profil

Permintaan ketiga menyasar berkas README di repository khusus yang namanya sama dengan username, bukan README tiap repository. URL pertamanya https://raw.githubusercontent.com/${username}/${username}/main/README.md; isinya dibaca dengan response.text() hanya bila response.ok (src/routes/llama/+server.js:83-108). Blok catch mencetak error lalu mengulang ke https://raw.githubusercontent.com/${username}/${username}/master/README.md, dan bila percobaan itu pun gagal, readmeResponse disetel '' (src/routes/llama/+server.js:83-108).

⚠️ Cadangan master tidak berjalan untuk respons 404. fetch tetap resolve pada 404, sehingga response.ok bernilai false tanpa melempar error; readmeResponse lalu tetap undefined dan kunci profile_readme hilang dari JSON.stringify.

Objek datas

Tiga hasil itu dirangkai menjadi satu objek datas (src/routes/llama/+server.js:111-131).

Kunci di datasSumberCatatan
name, bio, company, location, followers, following, public_reposprofileResponse dari GET /users/{username}tujuh field dipakai apa adanya
last_15_repositoriesrepoResponse dari GET /users/{username}/repos?sort=updated.map(...) memilih field, lalu .slice(0, 15) memotong hasil
profile_readmereadmeResponse dari main/README.md atau master/README.mdbisa undefined pada respons 404

Setiap repository dipangkas menjadi tujuh field: name, description, language, stargazers_count, open_issues_count, license, dan fork (src/routes/llama/+server.js:120-130). Objek datas kemudian disisipkan ke prompt lewat JSON.stringify(datas) (src/routes/llama/+server.js:133).

Batas dan Jebakan

⚠️ headers dideklarasikan sebagai let headers di scope modul, bukan di dalam POST, sehingga delete headers['Authorization'] mengubah objek yang dipakai bersama oleh permintaan lain pada isolate yang sama (src/routes/llama/+server.js:9-13).

⚠️ Permintaan daftar repository tidak memeriksa response.ok. Bila GitHub membalas dengan objek pesan (misalnya batas laju terlampaui), repoResponse.map(...) tidak bisa dijalankan karena nilainya bukan array (src/routes/llama/+server.js:78-81).

Akibat lain dari urutan ini: profileResponse baru terisi penuh setelah response.json() pada jalur normal, sedangkan nilai awal { status: 403 } hanya bertahan bila kedua permintaan profil gagal melempar error sebelum sempat menimpa variabel itu (src/routes/llama/+server.js:53-71).