Routing and API Documentation System β
Table of Contents β
- Overview and Architecture
- Quick Start
- HTTP Specifications and Best Practices
- Response Structure System
- MineAdmin Custom Annotations
- Practical Application Examples
- FAQs and Solutions
1. Overview and Architecture β
1.1 System Overview β
MineAdmin comes with a built-in complete API documentation generation system based on the Swagger/OpenAPI 3.0 specification, providing developers with powerful API documentation auto-generation and management capabilities.
Access Method: During local development, visit http://localhost:9503/swagger
to view the complete API documentation.
1.2 Architecture Layers β
Tech Stack Architecture
MineAdmin's API documentation system adopts a multi-layer architecture design:
- mineadmin/swagger - MineAdmin-specific Swagger annotation encapsulation layer
- hyperf/swagger - Hyperf framework's Swagger integration component
- zircote/swagger-php - PHP Swagger annotation processing core
- OpenAPI Specification - Industry-standard API documentation specification
1.3 System Architecture Diagram β
1.4 Core Advantages β
- Automated Documentation Generation: Auto-generates complete API documentation based on code annotations
- Type Safety: Strong type support ensures documentation matches actual code
- Real-time Synchronization: Documentation updates automatically with code changes
- Interactive Testing: Built-in Swagger UI supports direct API testing
2. Quick Start β
2.1 Basic Configuration β
Ensure your project has correctly installed the MineAdmin Swagger component:
composer require mineadmin/swagger
2.2 First API Interface β
Create a simple API interface:
<?php
namespace App\Http\Admin\Controller;
use App\Http\Common\Result;
use Mine\Swagger\Attributes\ResultResponse;
use Hyperf\Swagger\Annotation as OA;
#[OA\Tag(name: "User Management", description: "APIs related to users")]
class UserController extends AbstractController
{
#[OA\Get(
path: "/admin/user/info",
summary: "Get user info",
description: "Get detailed user information by user ID"
)]
#[ResultResponse(
instance: new Result(data: ["id" => 1, "name" => "John Doe"]),
title: "Success",
description: "Successfully retrieved user info"
)]
public function getUserInfo(): Result
{
return $this->success([
'id' => 1,
'name' => 'John Doe',
'email' => 'john@example.com'
]);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2.3 Access Documentation β
After starting the service, visit http://localhost:9503/swagger
to view the generated documentation.
3. HTTP Specifications and Best Practices β
3.1 RESTful API Design Principles β
MineAdmin recommends following RESTful architecture style to ensure API interface consistency and predictability.
3.1.1 HTTP Method Mapping β
3.1.2 Standard Route Design Pattern β
Taking user management module as an example, showing standard RESTful API design:
HTTP Method | Route Path | Description | Response Data |
---|---|---|---|
GET | /admin/user/list | Get user list (paginated) | User list data |
GET | /admin/user/{id} | Get single user details | Single user data |
POST | /admin/user | Create new user | Created user data |
PUT | /admin/user/{id} | Full update user info | Updated user data |
PATCH | /admin/user/{id} | Partial update user info | Updated user data |
DELETE | /admin/user/{id} | Delete user | Deletion confirmation |
3.1.3 Best Practice Recommendations β
Design Principles
Resource Naming: Use nouns not verbs, plural form
β /admin/users β /admin/getUsers
1
2Nested Resources: Reflect hierarchical relationships
β /admin/users/{id}/roles β /admin/user-roles?user_id={id}
1
2Status Code Semantics: Correctly use HTTP status codes
200 - Success 201 - Resource created 400 - Invalid parameters 401 - Unauthorized 403 - Forbidden 404 - Not found 500 - Server error
1
2
3
4
5
6
7Flexibility First: Standards are foundation, business needs are core
- Follow RESTful principles but not rigidly
- Prioritize sustainable business iteration
- Maintain team consistency
3.2 URL Design Specifications β
3.2.1 Naming Conventions β
// Recommended naming
GET /admin/users // Get user list
GET /admin/users/{id} // Get specific user
POST /admin/users // Create user
PUT /admin/users/{id} // Update user
DELETE /admin/users/{id} // Delete user
// Special operations
POST /admin/users/{id}/enable // Enable user
POST /admin/users/{id}/disable // Disable user
GET /admin/users/search // Search users
2
3
4
5
6
7
8
9
10
11
3.2.2 Parameter Passing Standards β
// Query params - for filtering, sorting, pagination
GET /admin/users?page=1&page_size=20&status=active&sort=created_at,desc
// Path params - for unique resource identification
GET /admin/users/123
// Request body - for complex data
POST /admin/users
Content-Type: application/json
{
"username": "johndoe",
"email": "john@example.com",
"roles": [1, 2, 3]
}
2
3
4
5
6
7
8
9
10
11
12
13
14
4. Response Structure System β
4.1 Unified Response Format β
MineAdmin uses the unified response structure \App\Http\Common\Result
to ensure all API interfaces return consistent formats.
4.2 Result Class Architecture β
4.3 Core Implementation Code β
4.3.1 Result Response Class β
<?php
declare(strict_types=1);
/**
* This file is part of MineAdmin.
*/
namespace App\Http\Common;
use Hyperf\Contract\Arrayable;
use Hyperf\Swagger\Annotation as OA;
/**
* Unified API response structure
* @template T
*/
#[OA\Schema(title: 'API Response Structure', description: 'Unified API response format')]
class Result implements Arrayable
{
public function __construct(
#[OA\Property(ref: 'ResultCode', title: 'Response code', description: 'Business code, different from HTTP status')]
public ResultCode $code = ResultCode::SUCCESS,
#[OA\Property(title: 'Response message', type: 'string', description: 'Response description')]
public ?string $message = null,
#[OA\Property(title: 'Response data', type: 'mixed', description: 'Actual business data')]
public mixed $data = []
) {
if ($this->message === null) {
$this->message = ResultCode::getMessage($this->code->value);
}
}
/**
* Convert to array format
*/
public function toArray(): array
{
return [
'code' => $this->code->value,
'message' => $this->message,
'data' => $this->data,
];
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php
namespace App\Http\Common\Controller;
use App\Http\Common\Result;
use App\Http\Common\ResultCode;
/**
* Base controller class
* Provides unified response methods
*/
abstract class AbstractController
{
/**
* Success response
*/
protected function success(mixed $data = [], ?string $message = null): Result
{
return new Result(ResultCode::SUCCESS, $message, $data);
}
/**
* Error response
*/
protected function error(?string $message = null, mixed $data = []): Result
{
return new Result(ResultCode::FAIL, $message, $data);
}
/**
* Custom response
*/
protected function json(ResultCode $code, mixed $data = [], ?string $message = null): Result
{
return new Result($code, $message, $data);
}
/**
* Paginated response
*/
protected function paginate(array $list, int $total, int $page = 1, int $pageSize = 10): Result
{
return $this->success([
'list' => $list,
'total' => $total,
'page' => $page,
'page_size' => $pageSize,
'total_pages' => ceil($total / $pageSize)
]);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?php
namespace App\Http\Admin\Controller;
use App\Http\Common\Controller\AbstractController as Base;
use Hyperf\Context\ApplicationContext;
use Hyperf\HttpServer\Contract\RequestInterface;
/**
* Admin controller base class
* Extends pagination functionality
*/
abstract class AbstractController extends Base
{
/**
* Get current page
*/
protected function getCurrentPage(): int
{
return (int) $this->getRequest()->input('page', 1);
}
/**
* Get page size
*/
protected function getPageSize(int $default = 10, int $max = 100): int
{
$size = (int) $this->getRequest()->input('page_size', $default);
return min($size, $max); // Limit max page size
}
/**
* Get request instance
*/
protected function getRequest(): RequestInterface
{
return ApplicationContext::getContainer()->get(RequestInterface::class);
}
/**
* Get sort params
*/
protected function getOrderBy(string $default = 'id'): array
{
$sort = $this->getRequest()->input('sort', $default);
$order = $this->getRequest()->input('order', 'asc');
return [$sort, in_array(strtolower($order), ['asc', 'desc']) ? $order : 'asc'];
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
4.4 ResultCode Enum Class β
MineAdmin provides a complete business status code enum system for standardizing API response states.
4.4.1 Core Implementation β
<?php
declare(strict_types=1);
/**
* This file is part of MineAdmin.
*/
namespace App\Http\Common;
use Hyperf\Constants\Annotation\Constants;
use Hyperf\Constants\Annotation\Message;
use Hyperf\Constants\ConstantsTrait;
use Hyperf\Swagger\Annotation as OA;
/**
* Business status code enum
* Provides standardized API response codes
*/
#[Constants]
#[OA\Schema(title: 'ResultCode', type: 'integer', default: 200, description: 'Business status code')]
enum ResultCode: int
{
use ConstantsTrait;
// Success states
#[Message('Operation successful')]
case SUCCESS = 200;
// General error states
#[Message('Operation failed')]
case FAIL = 500;
#[Message('Unauthorized access')]
case UNAUTHORIZED = 401;
#[Message('Insufficient permissions')]
case FORBIDDEN = 403;
#[Message('Resource not found')]
case NOT_FOUND = 404;
#[Message('Method not allowed')]
case METHOD_NOT_ALLOWED = 405;
#[Message('Unacceptable request format')]
case NOT_ACCEPTABLE = 406;
#[Message('Request entity processing error')]
case UNPROCESSABLE_ENTITY = 422;
// Business related errors
#[Message('Parameter validation failed')]
case VALIDATION_ERROR = 10001;
#[Message('Business logic error')]
case BUSINESS_ERROR = 10002;
#[Message('Database operation failed')]
case DATABASE_ERROR = 10003;
#[Message('External service call failed')]
case EXTERNAL_SERVICE_ERROR = 10004;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
4.4.2 Response Format Examples β
Different status codes correspond to different response formats:
// Success response
{
"code": 200,
"message": "Operation successful",
"data": {
"id": 1,
"username": "admin"
}
}
// Error response
{
"code": 10001,
"message": "Parameter validation failed",
"data": {
"errors": {
"username": ["Username cannot be empty"]
}
}
}
// Paginated response
{
"code": 200,
"message": "Operation successful",
"data": {
"list": [...],
"total": 100,
"page": 1,
"page_size": 20,
"total_pages": 5
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
4.5 Usage Best Practices β
4.5.1 Usage in Controllers β
class UserController extends AbstractController
{
public function index(): Result
{
try {
$users = $this->userService->getList();
return $this->success($users, 'Successfully retrieved user list');
} catch (ValidationException $e) {
return $this->json(ResultCode::VALIDATION_ERROR, [], $e->getMessage());
} catch (\Exception $e) {
return $this->error('System error, please try again later');
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
5. MineAdmin Custom Annotations β
MineAdmin provides three core custom Swagger annotations to simplify API documentation writing and maintenance. All annotations are located under the Mine\Swagger\Attributes\
namespace.
5.1 Annotation Architecture Overview β
5.2 ResultResponse Annotation β
Used to define single resource or operation response structures, automatically generating standard API response documentation.
5.2.1 Constructor Signature β
ResultResponse::__construct(
object|string $instance, // Response data class instance or class name
?string $title = null, // Response title
?array $examples = null, // Multiple examples array
?string $description = null, // Response description
mixed $example = Generator::UNDEFINED, // Single example
?array $headers = null, // Response headers
?int $response = 200 // HTTP status code
)
2
3
4
5
6
7
8
9
5.2.2 Parameter Details β
Parameter | Type | Required | Description |
---|---|---|---|
$instance | object|string | β | Response data class instance or name, supports auto |