Published CMS – API Response Contract

Posted by Spacened in Published CMS via Web

All API endpoints in Published CMS must return a **consistent JSON structure** compatible with both human and automated clients (e.g. PHP SDKs, GPT connectors).

---

## πŸ”– General Format

Every response (success or error) returns JSON like:

```json
{
"success": true,
"message": "Optional human-readable message",
"data": {},
"meta": {}
}
```

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `success` | `bool` | βœ… | Indicates success or failure. |
| `message` | `string` | ❌ | Optional message describing the result. |
| `data` | `array` or `object` | ❌ | The payload β€” model data, arrays, or paginated items. |
| `meta` | `object` | ❌ | Metadata container (pagination and other info). |

---

## 🟒 Success Responses

```php
return ApiResponse::success($data, $message = null, $code = 200);
```

**Example:**

```json
{
"success": true,
"message": "Category created successfully.",
"data": {
"id": 12,
"title": "Events",
"slug": "events",
"restricted": 0
}
}
```

---

## πŸ”΅ Paginated Responses

Paginated endpoints use:

```php
return ApiResponse::paginated($paginator, $message = null);
```

**Actual JSON output:**

```json
{
"success": true,
"data": [
{ "id": 1, "name": "Alice", "role": "mod" },
{ "id": 2, "name": "Bob", "role": "user" }
],
"meta": {
"pagination": {
"current_page": 1,
"last_page": 3,
"per_page": 15,
"total": 45
}
}
}
```

> βœ… This format aligns with the [JSON:API](https://jsonapi.org/) convention of nesting pagination and metadata inside `meta`.

---

## 🟑 Message-Only Responses

For endpoints that only confirm an action:

```php
return ApiResponse::message('Category deleted successfully.');
```

**Example:**

```json
{
"success": true,
"message": "Category deleted successfully."
}
```

---

## πŸ”΄ Error Responses

Errors use:

```php
return ApiResponse::error($message, $code = 400, $details = []);
```

**Example:**

```json
{
"success": false,
"message": "Validation failed.",
"data": {
"title": ["The title field is required."]
}
}
```

Laravel’s built-in exception handler automatically wraps validation and auth errors in this structure when exceptions are thrown.

---

## 🧩 Response Type Reference

| Type | Typical Use | Example Method |
| --- | --- | --- |
| **Success (200)** | Data retrieval | `CategoryController@index` |
| **Created (201)** | New resource | `CategoryController@store` |
| **Updated (200)** | Update actions | `CategoryController@update` |
| **Deleted (200)** | Soft delete | `CategoryController@destroy` |
| **Paginated (200)** | List endpoints | `CategoryController@listUsers` |
| **Message (200)** | Simple confirmation | `CategoryController@suspend` |
| **Error (4xx)** | Validation/conflict | `CategoryService@requestAccess` |

---

## βš™οΈ Developer Notes

- `ApiResponse` is defined in `App\Support\ApiResponse`.

- Pagination metadata **must** live under `meta.pagination` (not top-level).

- Non-paginated metadata (e.g. counts, filters) can be added to `meta` later.

- Always prefer returning full Eloquent models or collections β€” `ApiResponse` handles serialization.

- Clients (like the PHP `PublishedClient`) can safely assume:

- `data` contains all useful output,

- `meta.pagination` exists for paginated endpoints,

- and `message` is always a simple string.

Loading comments...