innopacks/restapi/README.md
Rama main · réplica de lectura del repositorio original.
# InnoShop REST API Documentation
This module uses [Scribe](https://scribe.knuckles.wtf/) (v5.x) to automatically generate API documentation from your Laravel codebase using PHP 8.1 Attributes.
## Features
- Automatic documentation generation from PHP Attributes
- OpenAPI 3.0 spec export
- Apifox integration for team collaboration
- Interactive "Try It Out" testing from the docs page
- Separate Front API and Panel API documentation
## Directory Structure
```
innopacks/restapi/
├── config/
│ ├── scribe_front.php # Front API Scribe config
│ └── scribe_panel.php # Panel API Scribe config
├── scripts/
│ ├── sync-apifox-sample.sh # Apifox sync script template
│ └── sync-apifox.sh # (gitignored) Script with real credentials
├── src/
│ ├── Commands/
│ │ └── SyncApifoxCommand.php # Artisan command for Apifox sync
│ ├── FrontApiControllers/ # Frontend API endpoints
│ ├── PanelApiControllers/ # Admin panel API endpoints
│ └── RestapiServiceProvider.php
└── routes/
├── front-api.php
└── panel-api.php
```
## Quick Start
### 1. Generate Documentation
```bash
# Generate Front API docs (available at /docs)
php artisan scribe:generate
# Generate Panel API docs (available at /docs/panel)
php artisan scribe:generate --config scribe_panel
```
### 2. View Documentation
- Front API: `http://localhost:8000/docs`
- Panel API: `http://localhost:8000/docs/panel`
### 3. OpenAPI Spec Files
After generation:
- Front API: `storage/app/scribe/openapi.yaml`
- Panel API: `storage/app/scribe_panel/openapi.yaml`
## Sync to Apifox
### Option 1: Artisan Command (Recommended)
Add to your `.env`:
```env
APIFOX_TOKEN=your-apifox-token
APIFOX_FRONT_PROJECT_ID=your-front-project-id
APIFOX_PANEL_PROJECT_ID=your-panel-project-id
# Optional: if your account uses another region (see Apifox Open API docs)
# APIFOX_API_BASE_URL=https://api.apifox.com
# Optional: do not remove endpoints that are not in the OpenAPI file
# APIFOX_KEEP_UNMATCHED=true
```
**Project ID** must be the numeric **Project ID** from Apifox **Project Settings → Open API** (not the team ID or online doc URL slug). If sync “succeeds” but no interfaces appear, run `php artisan apifox:sync -v` and confirm counters; the command sends OpenAPI as a JSON string in `input`, as required by the Apifox API.
Run the sync command:
```bash
# Sync both Front and Panel APIs
php artisan apifox:sync
# Sync only Front API
php artisan apifox:sync --type=front
# Sync only Panel API
php artisan apifox:sync --type=panel
# Override credentials via command line
php artisan apifox:sync --token=your-token --front-project=123 --panel-project=456
# Verbose: print HTTP status and full Apifox JSON response
php artisan apifox:sync -v
# Keep endpoints in Apifox that are not in the file (disable sync-delete)
php artisan apifox:sync --keep-unmatched
```
### Option 2: Shell Script
```bash
# Copy the sample script and fill in your credentials
cp innopacks/restapi/scripts/sync-apifox-sample.sh innopacks/restapi/scripts/sync-apifox.sh
# Edit sync-apifox.sh with your credentials, then run
bash innopacks/restapi/scripts/sync-apifox.sh
```
Note: `sync-apifox.sh` with real credentials is gitignored.
## Configuration
Two separate Scribe config files control documentation generation:
| Config File | HTML | OpenAPI | Postman | API routes |
|---|---|---|---|---|
| `config/scribe_front.php` (merged as `config/scribe.php`) | `/docs` | `/docs.openapi` | `/docs.postman` | `api/*` (excluding `api/panel/*`) |
| `config/scribe_panel.php` | `/docs/panel` | `/docs/panel.openapi` | `/docs/panel.postman` | `api/panel/*` |
Front and panel use different Sanctum tokens (`customer-token` vs `admin-token`); each OpenAPI file only describes its own prefix. Regenerate both after code changes: `php artisan scribe:generate` and `php artisan scribe:generate --config=scribe_panel`.
To publish config files to the main `config/` directory:
```bash
php artisan vendor:publish --tag=innoshop-scribe-config
```
## Adding Annotations
Use PHP 8.1 Attributes on your controllers:
```php
use Knuckles\Scribe\Attributes\Authenticated;
use Knuckles\Scribe\Attributes\BodyParam;
use Knuckles\Scribe\Attributes\Endpoint;
use Knuckles\Scribe\Attributes\Group;
use Knuckles\Scribe\Attributes\QueryParam;
use Knuckles\Scribe\Attributes\Unauthenticated;
use Knuckles\Scribe\Attributes\UrlParam;
#[Group('Front - Products')]
class ProductController extends BaseController
{
#[Endpoint('List products')]
#[Unauthenticated]
#[QueryParam('per_page', 'integer', required: false, example: 15)]
#[QueryParam('sort', 'string', required: false, example: 'id')]
public function index(Request $request): mixed { ... }
#[Endpoint('Get product details')]
#[UrlParam('product', 'integer', description: 'Product ID')]
public function show(Product $product): mixed { ... }
}
```
## Scribe Attributes Reference
| Attribute | Level | Description |
|---|---|---|
| `#[Group('name')]` | Class | Group related endpoints |
| `#[Endpoint('title')]` | Method | Endpoint title and description |
| `#[Authenticated]` | Class/Method | Requires authentication |
| `#[Unauthenticated]` | Class/Method | Public endpoint |
| `#[QueryParam(...)]` | Method | Query string parameter |
| `#[UrlParam(...)]` | Method | URL path parameter |
| `#[BodyParam(...)]` | Method | Request body parameter |
## Troubleshooting
### Documentation not generating
1. Clear cache: `php artisan cache:clear && php artisan config:clear`
2. Run with verbose output: `php artisan scribe:generate -v`
### Routes not showing in docs
1. Verify route prefix matches the config (`api/*` for front, `api/panel/*` for panel)
2. Ensure the controller method has `#[Endpoint(...)]` attribute
3. Check route is not in the `exclude` list
## Resources
- [Scribe Documentation](https://scribe.knuckles.wtf/)
- [Scribe PHP Attributes](https://scribe.knuckles.wtf/laravel/reference/annotations)
- [OpenAPI Specification](https://swagger.io/specification/)
## License
Same as InnoShop.