Kryve Studio - GitHub API PHP wrapper untuk GitHub REST API
Introduction
Library PHP sederhana untuk mengakses GitHub REST API.
Dibangun dengan cURL dan JSON, tanpa dependensi HTTP library tambahan.
Setiap response dikembalikan sebagai array PHP.
Package ini dibuat oleh Kryve Studio dan dirilis sebagai open-source.
Installation
Via Composer
composer require kryvestudio/github-api
Requirements
- PHP 8.3+
ext-curlext-json- Composer (PSR-4 autoloading)
Authentication
GitHub API butuh token untuk sebagian besar endpoint (terutama yang private atau write). Library ini support 3 metode auth:
| Metode | Constructor | Kapan dipakai |
|---|---|---|
| Bearer Token | new Client($token) |
Recommended: token doang, ga perlu username |
| Basic Auth | new Client($token, $baseUrl, $username) |
Kalau API butuh username:password (legacy) |
| No Auth | new Client() |
Public endpoints aja (rate limit lebih rendah) |
Quickstart
Contoh paling sederhana: ambil data user publik tanpa token:
<?php
require __DIR__ . '/vendor/autoload.php';
use Kryve\GithubApi\Client;
$client = new Client();
$user = $client->get('/users/kryvestudio');
echo "Login: {$user['login']}\n";
echo "Nama: " . ($user['name'] ?? '-') . "\n";
echo "Bio: " . ($user['bio'] ?? '-') . "\n";
Bearer Token
Set token di environment variable GITHUB_TOKEN, lalu baca pake getenv():
<?php
require __DIR__ . '/vendor/autoload.php';
use Kryve\GithubApi\Client;
use Kryve\GithubApi\Api\User;
use Kryve\GithubApi\Api\Repos;
$token = getenv('GITHUB_TOKEN') ?: null;
$client = new Client($token);
$user = new User($client);
$data = $user->get('kryvestudio');
echo "Bio: {$data['bio']}\n";
$repos = new Repos($client);
$list = $repos->forUser('kryvestudio');
echo "Total repo: " . count($list) . "\n";
Basic Auth
Kalau perlu Basic Auth (misal token + username), tinggal tambah parameter ketiga:
<?php
require __DIR__ . '/vendor/autoload.php';
use Kryve\GithubApi\Client;
$client = new Client(
token: 'ghp_xxxxx',
baseUrl: 'https://api.github.com',
username: 'kryvestudio'
);
$result = $client->get('/user');
print_r($result);
No Auth (Public)
Tanpa token, cuma bisa akses endpoint publik. Rate limit lebih rendah (60 req/jam vs 5000 req/jam kalau pake token).
<?php
require __DIR__ . '/vendor/autoload.php';
use Kryve\GithubApi\Client;
$client = new Client();
$user = $client->get('/users/kryvestudio');
Client API Reference
Kryve\GithubApi\Client adalah class inti yang handle semua komunikasi HTTP via cURL.
__construct(?string $token, string $baseUrl, ?string $username)
| Parameter | Type | Default | Deskripsi |
|---|---|---|---|
$token |
?string |
null |
GitHub personal access token |
$baseUrl |
string |
'https://api.github.com' |
Base URL API (ganti kalau pake GitHub Enterprise) |
$username |
?string |
null |
Username untuk Basic Auth (optional) |
get(string $endpoint, array $params): array
Kirim GET request ke endpoint GitHub API.
| Parameter | Type | Deskripsi |
|---|---|---|
$endpoint |
string |
Path endpoint, misal '/users/kryvestudio' |
$params |
array |
Query parameters (optional), misal ['per_page' => 100] |
Return: array - response JSON yang sudah di-decode.
Throws: ApiException kalau HTTP status ≥ 400 atau ada error cURL.
http_build_query().
Contoh: $client->get('/search/users', ['q' => 'kryve']).
User API
Kryve\GithubApi\Api\User
<?php
use Kryve\GithubApi\Client;
use Kryve\GithubApi\Api\User;
$client = new Client(getenv('GITHUB_TOKEN') ?: null);
$user = new User($client);
// GET /users/:username
$data = $user->get('kryvestudio');
echo $data['login']; // "kryvestudio"
echo $data['name']; // "Kryve Studio"
echo $data['bio']; // "Indie web dev studio..."
echo $data['public_repos'];// 12
echo $data['followers']; // 5
| Method | Endpoint | Return |
|---|---|---|
get(string $username) |
GET /users/:username |
array |
Repos API
Kryve\GithubApi\Api\Repos
<?php
use Kryve\GithubApi\Client;
use Kryve\GithubApi\Api\Repos;
$client = new Client(getenv('GITHUB_TOKEN') ?: null);
$repos = new Repos($client);
// Repositori milik user
$userRepos = $repos->forUser('kryvestudio');
foreach ($userRepos as $repo) {
echo $repo['name'] . ' - ' . ($repo['description'] ?? '-') . "\n";
}
// Repositori milik organisasi
$orgRepos = $repos->forOrg('laravel');
echo "Total repo Laravel: " . count($orgRepos) . "\n";
// Dengan query params
$filtered = $repos->forUser('kryvestudio', ['type' => 'public', 'per_page' => 5]);
| Method | Endpoint | Return |
|---|---|---|
forUser(string $username, array $params) |
GET /users/:username/repos |
array |
forOrg(string $org, array $params) |
GET /orgs/:org/repos |
array |
Parameter $params bisa diisi:
type-all,public,private,forks,sources,membersort-created,updated,pushed,full_namedirection-asc,descper_page- max 100 (default 30)page- pagination
Issues API
Kryve\GithubApi\Api\Issues
<?php
use Kryve\GithubApi\Client;
use Kryve\GithubApi\Api\Issues;
$client = new Client(getenv('GITHUB_TOKEN') ?: null);
$issues = new Issues($client);
// GET /repos/:owner/:repo/issues
$list = $issues->list('laravel', 'framework');
foreach ($list as $issue) {
echo "[{$issue['state']}] {$issue['title']} - @{$issue['user']['login']}\n";
}
// Filter: cuma open issues, 10 per page
$openIssues = $issues->list('laravel', 'framework', [
'state' => 'open',
'per_page' => 10,
]);
| Method | Endpoint | Return |
|---|---|---|
list(string $owner, string $repo, array $params) |
GET /repos/:owner/:repo/issues |
array |
Parameter $params bisa diisi:
state-open,closed,alllabels- comma-separated label namessort-created,updated,commentsdirection-asc,descsince- ISO 8601 timestampper_page,page
Error Handling
Semua error (HTTP 400+) dan error cURL dilempar sebagai
Kryve\GithubApi\Exception\ApiException.
ApiException
<?php
use Kryve\GithubApi\Client;
use Kryve\GithubApi\Exception\ApiException;
$client = new Client();
try {
$client->get('/users/nonexistent_user_xyz');
} catch (ApiException $e) {
echo "Message: " . $e->getMessage() . "\n"; // "Not Found"
echo "HTTP Code: " . $e->getCode() . "\n"; // 404
echo "Response Body:\n";
print_r($e->getResponseBody()); // array dari GitHub
if ($e->getCode() === 404) {
// handle not found
} elseif ($e->getCode() === 401) {
// handle unauthorized
} elseif ($e->getCode() === 403) {
// rate limited? cek $e->getResponseBody()
}
}
| Method | Return | Deskripsi |
|---|---|---|
getMessage() |
string |
Pesan error dari GitHub (misal "Not Found") |
getCode() |
int |
HTTP status code (404, 401, 500, dll) |
getResponseBody() |
?array |
Full response JSON dari GitHub (nullable) |
- 401 - token invalid / expired
- 403 - rate limit exceeded / forbidden
- 404 - resource gak ditemukan (user, repo, dll)
- 422 - validation error (parameter salah)
Testing
Library ini pake PHPUnit untuk integration test (panggil API asli).
composer test
Atau langsung:
vendor\bin\phpunit
Contoh test yang ada:
<?php
namespace Kryve\GithubApi\Tests;
use PHPUnit\Framework\TestCase;
use Kryve\GithubApi\Client;
use Kryve\GithubApi\Exception\ApiException;
class ClientTest extends TestCase
{
private Client $client;
protected function setUp(): void
{
$token = getenv('GITHUB_TOKEN') ?: null;
$this->client = new Client($token);
}
public function testGetUserReturnsArray(): void
{
$result = $this->client->get('/users/kryvestudio');
$this->assertIsArray($result);
$this->assertArrayHasKey('login', $result);
}
public function testInvalidEndpointThrowsException(): void
{
$this->expectException(ApiException::class);
$this->client->get('/users/nonexistent_user_xyz_999');
}
}
Project Structure
├── src/
│ ├── Client.php # HTTP client utama (cURL wrapper)
│ ├── Api/
│ │ ├── User.php # GET /users/:username
│ │ ├── Repos.php # GET /orgs/:org/repos & /users/:username/repos
│ │ └── Issues.php # GET /repos/:owner/:repo/issues
│ └── Exception/
│ └── ApiException.php # Custom exception
├── tests/
│ └── ClientTest.php # PHPUnit integration tests
├── docs/
│ └── index.html # Dokumentasi ini
├── composer.json
├── phpunit.xml
├── .gitignore
├── .env.example
└── README.md
src/Api/, isi class dengan
constructor terima Client, dan panggil
$this->client->get('/path/baru').