diff --git a/README.md b/README.md index b0f56e4..2d7fa91 100644 --- a/README.md +++ b/README.md @@ -399,6 +399,20 @@ Failed responses are mapped in `GithubConnector`: Pull requests are welcome. Run `composer test` before opening one. +## Patterns and Architecture + +### 3-Way CLI Pattern + +This package provides three complementary ways to interact with the GitHub API: + +| Pattern | Use Case | Example | +|---------|----------|---------| +| **Facade** (`Github::`) | Quick, static access | `Github::repos()->all()` | +| **Resources** (`repos()`) | Organized, grouped methods | `Github::repos()->all()` | +| **CLI** (`php artisan github-client`) | Command-line scripts | `php artisan github-client test` | + +The `Github` class is the **core package** that ties all three together. See [docs/3WAY-CLI-PATTERN.md](./docs/3WAY-CLI-PATTERN.md) for details. + ## License MIT. See [LICENSE.md](LICENSE.md). diff --git a/docs/3WAY-CLI-PATTERN.md b/docs/3WAY-CLI-PATTERN.md new file mode 100644 index 0000000..ffd243a --- /dev/null +++ b/docs/3WAY-CLI-PATTERN.md @@ -0,0 +1,183 @@ +# 3-Way CLI Pattern + +This package implements a **3-Way CLI Pattern** that provides three complementary ways to interact with the GitHub API: + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ 3-Way CLI Pattern │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ 1. Facade (Github::) 2. Resources (repos(), issues()) 3. CLI Command │ +│ Static Access Method Grouping Artisan Command │ +└─────────────────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────────────────┐ +│ Core Package Role │ +│ The Github Class │ +│ Orchestrates all three access patterns through a single, consistent API │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +## The Three Ways + +### Way 1: Facade Access (`Github::`) + +Use the `Github` facade for static, convenient access to the API: + +```php +use JordanPartridge\GithubClient\Facades\Github; + +// List repositories +$repos = Github::repos()->all()->dto(); + +// Get a specific repository +$repo = Github::getRepo('laravel/framework'); +``` + +**Use when**: You want the simplest, most direct access to the API without dependency injection. + +### Way 2: Resource Methods (`repos()`, `issues()`) + +Access the API through resource-specific methods that group related functionality: + +```php +use JordanPartridge\GithubClient\Facades\Github; +use JordanPartridge\GithubClient\ValueObjects\Repo; + +// Repository resource +$repos = Github::repos()->all()->dto(); +$name = Repo::fromFullName('laravel/framework'); +$repo = Github::repos()->get($name); +Github::repos()->delete($name); + +// Issue resource +$issue = Github::issues()->create($owner, $repo, $title, $body); + +// Pull request resource +$pullRequests = Github::pullRequests()->all($owner, $repo); +``` + +**Use when**: You want organized access to related API endpoints, or when injecting the client for testability. + +### Way 3: CLI Command (`php artisan github-client`) + +Use Artisan commands for quick inspections and testing from the command line: + +```bash +# Test the GitHub API connection +php artisan github-client test + +# Show repository information +php artisan github-client repo --repo=laravel/framework + +# Show recent commits +php artisan github-client commits --repo=laravel/framework --limit=10 +``` + +**Use when**: You need quick access to GitHub data without writing PHP code, or for debugging. + +## The Core Package Role + +The `Github` class is the **core package** that ties all three access methods together: + +```php +namespace JordanPartridge\GithubClient; + +use JordanPartridge\GithubClient\Connectors\GithubConnector; +use JordanPartridge\GithubClient\Resources\RepoResource; +use JordanPartridge\GithubClient\Resources\IssuesResource; +use JordanPartridge\GithubClient\Resources\PullRequestResource; +// ... all other resources + +class Github +{ + public function __construct( + protected GithubConnector $connector, + ) {} + + // Resource methods - connect to resources + public function repos(): RepoResource + { + return new RepoResource($this); + } + + public function issues(): IssuesResource + { + return new IssuesResource($this); + } + + public function pullRequests(): PullRequestResource + { + return new PullRequestResource($this); + } + + // ... all other resource methods +} +``` + +### Core Responsibilities + +1. **Resource Factory**: Creates resource instances (`repos()`, `issues()`, etc.) + +2. **Connector Holder**: Maintains a single `GithubConnector` instance for HTTP requests + +3. **Authentication Gateway**: Routes authentication through `GithubConnector` + +4. **Rate Limit Tracking**: Provides rate limit information via `getRateLimitStatus()` + +5. **GitHub App Support**: Handles installation-based authentication via `forInstallation()` and `withApp()` + +### How the Core Ties Everything Together + +``` +┌──────────────┐ ┌──────────────┐ ┌──────────────┐ +│ Facade │ │ Resources │ │ CLI │ +│ Github:: │ │ repos(), │ │ artisan │ +│ static calls │────▶│ issues() │────▶│ github-client│ +└──────────────┘ │ pullRequests()│ └──────────────┘ + └──────────────┘ + │ + ▼ + ┌──────────────┐ + │ Core │ + │ Github │ + │ class │ + └──────────────┘ + │ + ▼ + ┌──────────────┐ + │ Connector │ + │ (HTTP) │ + └──────────────┘ + │ + ▼ + ┌──────────────┐ + │ GitHub API │ + └──────────────┘ +``` + +## Choosing the Right Pattern + +| Scenario | Recommended Pattern | +|----------|---------------------| +| Quick script or quick test |_facade (`Github::`) | +| Class-based architecture |_Inject `Github` class | +| Related endpoint group | Use resource (`repos()`) | +| CI/CD scripts or shell automation | CLI command | +| Debugging | CLI command | + +## Example: All Three Ways to List Repositories + +```php +// Way 1: Facade +use JordanPartridge\GithubClient\Facades\Github; +$repos = Github::repos()->all()->dto(); + +// Way 2: Resource +$repos = Github::repos()->all()->dto(); + +// Way 3: CLI +// php artisan github-client list-repos +``` + +All three ways use the same underlying core package and return the same results. diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index da2cbbe..df2d495 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -2,6 +2,16 @@ `jordanpartridge/github-client` is a Laravel package for the GitHub REST API. It is built on [Saloon](https://docs.saloon.dev) and returns typed PHP objects instead of raw arrays. It requires PHP 8.2 or newer and Laravel 11, 12, or 13. CI runs the suite on PHP 8.2, 8.3, and 8.4. +## 3-Way CLI Pattern + +This package implements a **3-Way CLI Pattern** with three complementary ways to access the GitHub API: + +1. **Facade** (`Github::`) - Static access for convenience +2. **Resources** (`repos()`, `issues()`) - Grouped methods by feature area +3. **CLI Command** (`php artisan github-client`) - Command-line interface + +The `Github` class is the **core package** that orchestrates all three access patterns. See [docs/3WAY-CLI-PATTERN.md](./3WAY-CLI-PATTERN.md) for a detailed explanation. + ## Layers ``` diff --git a/docs/README.md b/docs/README.md index 5b4c769..0e80a34 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,5 +5,6 @@ The [README](../README.md) is the install and usage guide. The pages below cover 1. [Getting started](./getting-started.md) 2. [API reference](./api-reference.md) 3. [Authentication and errors](./advanced-usage.md) -4. [How the client is put together](./core-concepts.md) -5. [Architecture](./ARCHITECTURE.md) +4. [3-Way CLI Pattern](./3WAY-CLI-PATTERN.md) +5. [How the client is put together](./core-concepts.md) +6. [Architecture](./ARCHITECTURE.md) diff --git a/docs/core-concepts.md b/docs/core-concepts.md index e99d6d6..7f66902 100644 --- a/docs/core-concepts.md +++ b/docs/core-concepts.md @@ -1,5 +1,13 @@ # How the client is put together +This package implements a **3-Way CLI Pattern** that provides three complementary ways to interact with the GitHub API: + +1. **Facade** (`Github::`) - Static access for convenience +2. **Resources** (`repos()`, `issues()`) - Grouped methods by feature area +3. **CLI Command** (`php artisan github-client`) - Command-line interface + +The `Github` class is the **core package** that orchestrates all three access patterns. See [3-Way CLI Pattern](./3WAY-CLI-PATTERN.md) for a detailed explanation. + `GithubClientServiceProvider` registers four things: - The `github-client` config file @@ -14,3 +22,15 @@ DTOs in `src/Data` are plain PHP objects with a `fromArray()` or `fromApiRespons `Repo::fromFullName('owner/repo')` checks that the string has one slash and that each side matches `[a-zA-Z0-9._-]+`. Enums replace a few query strings: `Visibility`, `Sort`, `Direction`, `Repos\Type`, `Issues\State`, `Issues\Sort`, `Pulls\State`, `Pulls\Sort`, and `MergeMethod`. Pull request list filters are still a plain array. + +## The Core Package Role + +The `Github` class is the **core package** that ties all three access patterns together: + +- **Resource Factory**: Creates resource instances (`repos()`, `issues()`, etc.) +- **Connector Holder**: Maintains a single `GithubConnector` for HTTP requests +- **Authentication Gateway**: Routes all authentication through `GithubConnector` +- **Rate Limit Tracking**: Provides rate limit info via `getRateLimitStatus()` +- **GitHub App Support**: Handles installation-based auth via `forInstallation()` and `withApp()` + +All three ways to access the API (Facade, Resources, CLI) use the same `Github` core class.