### Install and load MixerApi/JsonLdView Source: https://mixerapi.com/plugins/json-ld-view Install the plugin via Composer and load it using the CakePHP CLI. This step can be skipped if MixerAPI is already installed. ```bash composer require mixerapi/json-ld-view bin/cake plugin load MixerApi/JsonLdView ``` -------------------------------- ### Install SwaggerBake for OpenAPI Source: https://mixerapi.com/install Run the SwaggerBake installer to define necessary configurations for OpenAPI documentation. ```bash bin/cake swagger install ``` -------------------------------- ### Install with Composer and Load Plugin Source: https://mixerapi.com/plugins/exception-render Install the plugin via Composer and load it using the CakePHP shell command. This is the standard installation method. ```bash composer require mixerapi/exception-render bin/cake plugin load MixerApi/ExceptionRender ``` -------------------------------- ### Install Swagger Bake via Composer Source: https://mixerapi.com/plugins/cakephp-swagger-bake Run this command to install the plugin and its dependencies. ```bash composer require cnizzardini/cakephp-swagger-bake ``` -------------------------------- ### Run automated MixerAPI installation Source: https://mixerapi.com/install The automated installer updates configuration files and creates a welcome page at the index route. ```bash bin/cake mixerapi install ``` -------------------------------- ### Install CollectionView with Composer and load plugin Source: https://mixerapi.com/plugins/collection-view Install the plugin via Composer and load it using the CakePHP plugin shell command. This is required unless MixerAPI is already installed. ```bash composer require mixerapi/collection-view bin/cake plugin load MixerApi/CollectionView ``` -------------------------------- ### Install MixerApi HAL View via Composer and CLI Source: https://mixerapi.com/plugins/hal-view Use Composer to install the package and the CakePHP CLI to load the plugin. ```bash composer require mixerapi/hal-view bin/cake plugin load MixerApi/HalView ``` -------------------------------- ### JWK Set example response Source: https://mixerapi.com/plugins/jwt-auth Example JSON response from the JWK Set endpoint, showing the public key details. ```json { "keys": [ { "kty": "RSA", "use": "sig", "alg": "RS256", "kid": "1", "n": "wk865HbUKadJU-Mh-Iv2Z_30ZOMclkK1cbuiTVkINy_R9oHoAht2DS788q_Sll38dtTB4bzptd0u6k4cJd6Lj6nVQTe1uRyuAU47tqitiJmEXX_2SHIRv6aj4vygIfqr1FtQMHPlBW7r4q840H5mh_Z-E_a7d27QbtJ3eYNEiFow6LLvl17_7bdaenlwccY0j-PY1GzL7UwG8uHBZ78ZOcvu_GgaYC5suRrJrV_6_Qu6lySXObDaajr6Foz0m-z4Aj7KA8KmAiM_Rw_Yqm_KqPT3YBGj83TxeEiMPkrMYry123hFQYm09EO2Az9lGjr-PQc6SR08SDqZ3zbwe9iam55dzVZ-vQF3ASnZpBHyIDhCI7PFShceFI1Sv0RW7-Tl0uM2jQa1RyEpFle1xc0RxSFZium0aGMnFuE2W9JDERPw47wFZx2kSk1nB6PDK6XPLJLi_db0VrP5m5z2HDWeYVmsuAVFm6-l1PjiGH4G1TpuYfPKP2P8K-kveo1Ddm14IJSWfcACeAF_gx644Ua_IJ8wS98dQqE-R-jzfEv7aLBacP5_thCUbHfCRrAgtM5lBAM_1tfQ4XsOLnFWkl4arm3TzN2wCjjuqxipgwpUtY_SN6SXhJW4MW2qHVKtHtXl9haF5gEDBL7twDsFozYZCc5k0d85EgfJ5Jn7ZSAgwXk", "e": "AQAB" } ] } ``` -------------------------------- ### Install MixerApi/Bake with Composer and CakePHP plugin loader Source: https://mixerapi.com/plugins/bake Install the MixerApi/Bake plugin via Composer and load it with the CakePHP plugin loader. This step can be skipped if MixerAPI is already installed. ```bash composer require mixerapi/bake bin/cake plugin load MixerApi/Bake ``` -------------------------------- ### Install MixerApi REST plugin via Composer Source: https://mixerapi.com/plugins/rest Install the plugin using Composer and load it with the CakePHP shell command. ```bash composer require mixerapi/rest bin/cake plugin load MixerApi/Rest ``` -------------------------------- ### OpenApiOperation usage example Source: https://mixerapi.com/plugins/cakephp-swagger-bake/docs/attributes Demonstrates applying the OpenApiOperation attribute to a controller action and the resulting OpenAPI output. ```php #[OpenApiOperation( summary: 'operation title', description: 'a description', tagNames: ['Internal API', 'External API'], externalDocs: [ 'url' => 'https://github.com/cnizzardini/cakephp-swagger-bake', 'description' => 'Check out the documentation' ] )] public function index() ``` ```yaml get: operationId: actors:index:get summary: operation title description: a description tags: - Internal API - External API externalDocs: url: https://github.com/cnizzardini/cakephp-swagger-bake description: Check out the documentation ``` -------------------------------- ### JSON-LD Item Output Source: https://mixerapi.com/plugins/json-ld-view Example JSON-LD output for a single entity. ```json { "@id": "/languages/1", "@type": "https://schema.org/Language", "@context": "/context/Language", "id": 1, "name": "English" } ``` -------------------------------- ### OpenApiPathParam usage example Source: https://mixerapi.com/plugins/cakephp-swagger-bake/docs/attributes Demonstrates modifying an existing path parameter using OpenApiPathParam and the resulting OpenAPI specification. ```php #[OpenApiPathParam(name: 'id', type: 'integer', format: 'int64', description: 'ID')] public function view($id) {} ``` ```yaml parameters: - name: id required: true schema: description: ID type: integer format: int64 ``` -------------------------------- ### Controller Action for Items Source: https://mixerapi.com/plugins/json-ld-view Example controller action for returning a single entity as JSON-LD. ```php #src/Controller/LanguagesController.php public function view($id = null) { $this->request->allowMethod('get'); $languages = $this->Languages->get($id); $this->set('languages', $languages); $this->viewBuilder()->setOption('serialize', 'languages'); } ``` -------------------------------- ### Configure RSA keys in config/mixerapi_jwtauth.php Source: https://mixerapi.com/plugins/jwt-auth Example configuration for RS256 algorithm with a key pair. Keys are loaded from files in config/keys/1/ and should not be stored in version control. ```php # in config/mixerapi_jwtauth.php return [ 'MixerApi.JwtAuth' => [ 'alg' => 'RS256', 'keys' => [ [ 'kid' => '1', 'public' => file_get_contents(CONFIG . 'keys' . DS . '1' . DS . 'public.pem'), 'private' => file_get_contents(CONFIG . 'keys' . DS . '1' . DS . 'private.pem'), ] ] ] ]; ``` -------------------------------- ### Install MixerAPI via Composer Source: https://mixerapi.com/ Use this command to add the MixerAPI package to your existing CakePHP project. ```bash composer require mixerapi/mixerapi ``` -------------------------------- ### Install MixerApi JwtAuth via Composer Source: https://mixerapi.com/plugins/jwt-auth Use composer to add the library to your CakePHP application. ```bash composer require mixerapi/jwt-auth ``` -------------------------------- ### curl GET /actors with HAL accept header Source: https://mixerapi.com/plugins/hal-view Command to test the HAL endpoint. Sends a GET request to /actors with the Accept header application/hal+json to receive HAL-formatted JSON. ```bash # json curl -X GET "http://localhost:8765/actors" -H "accept: application/hal+json" ``` -------------------------------- ### Manually load MixerApi/Crud in Application Source: https://mixerapi.com/plugins/crud Manually loads the plugin in your Application class after Composer installation. Place this in the bootstrap() method. ```php # src/Application.php public function bootstrap(): void { $this->addPlugin('MixerApi/Crud'); } ``` -------------------------------- ### JSON-LD Collection Output Source: https://mixerapi.com/plugins/json-ld-view Example JSON-LD output for a collection, including Hydra pagination metadata. ```json { "@context": "/context/Film", "@id": "/films", "@type": "Collection", "pageItems": 20, "totalItems": 1, "view": { "@id": "/films", "@type": "PartialCollectionView", "next": "/films?page=2", "prev": "", "first": "", "last": "/films?page=50" }, "member": [ { "id": 1, "title": "ACADEMY DINOSAUR", "description": "A Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies", "modified": "2006-02-15T05:03:42+00:00", "language": { "id": 1, "name": "English", "@id": "/languages/1", "@type": "https://schema.org/Language", "@context": "/context/Language" }, "@id": "/films/1", "@type": "https://schema.org/Movie", "@context": "/context/Film" } ] } ``` -------------------------------- ### Manually load plugin in Application.php Source: https://mixerapi.com/plugins/collection-view Alternative to the plugin shell command. Add the plugin in the bootstrap() method of your Application class after composer install. ```php # src/Application.php public function bootstrap(): void { // other logic... $this->addPlugin('MixerApi/CollectionView'); } ``` -------------------------------- ### Controller Action for Collections Source: https://mixerapi.com/plugins/json-ld-view Example controller action for returning a collection of entities, which will be serialized as JSON-LD with pagination data. ```php #src/Controller/FilmsController.php public function index() { $this->request->allowMethod('get'); $actors = $this->paginate($this->Films, [ 'contain' => ['Languages'], ]); $this->set(compact('films')); $this->viewBuilder()->setOption('serialize', 'films'); } ``` -------------------------------- ### OpenApiDtoRequestBody with constructor property promotion Source: https://mixerapi.com/plugins/cakephp-swagger-bake/docs/attributes Example of using the OpenApiDtoRequestBody attribute with PHP constructor property promotion. ```php class ActorDto { public function __construct( #[OpenApiDtoRequestBody(name: 'name', isRequired: true)] public string $name, #[OpenApiDtoRequestBody(name: 'age', type: 'integer', format: 'int32', isRequired: true, minimum: 1, maximum: 100)] private int $age ) { } ``` -------------------------------- ### XML collection response sample Source: https://mixerapi.com/plugins/collection-view Example XML response for a collection request. Shows pagination metadata under and data under . ```xml /films?page=3&direction=desc 20 1000 50 /films?page=4 /films?page=2 /films /films?page=50 1 PENELOPE GUINESS 2/15/06, 4:34 AM 1 ACADEMY DINOSAUR A Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies 2006 1 6 86 PG Deleted Scenes,Behind the Scenes 2/15/06, 5:03 AM ``` -------------------------------- ### OpenAPI specification output for OpenApiResponse Source: https://mixerapi.com/plugins/cakephp-swagger-bake/docs/attributes The resulting OpenAPI specification generated from the OpenApiResponse attribute example. ```yaml '200': content: application/json: schema: type: array items: $ref: '#/components/schemas/Actor' '40x': content: application/xml: schema: type: object items: $ref: '#/components/schemas/Exception' ``` -------------------------------- ### OpenApiQueryParam OpenAPI Output Source: https://mixerapi.com/plugins/cakephp-swagger-bake/docs/attributes The resulting OpenAPI specification generated from the OpenApiQueryParam attribute example. ```yaml parameters: - name: option in: query schema: type: string enum: - A - B - C - $ref: #/x-my-project/components/parameters/my-parameter ``` -------------------------------- ### OpenApiDtoRequestBody in DTO class Source: https://mixerapi.com/plugins/cakephp-swagger-bake/docs/attributes Example of applying the OpenApiDtoRequestBody attribute to class properties. ```php class ActorDto { #[OpenApiDtoRequestBody(name: 'name', isRequired: true)] private string $name; #[OpenApiDtoRequestBody(name: 'age', type: 'integer', format: 'int32', isRequired: true, minimum: 1, maximum: 100)] private int $age; ``` -------------------------------- ### OpenApiSchema Attribute Example Source: https://mixerapi.com/plugins/cakephp-swagger-bake/docs/attributes Demonstrates applying the OpenApiSchema attribute to an entity class to set visibility and title. ```php #[OpenApiSchema(visbility: OpenApiSchema::VISIBLE_ALWAYS, title: 'Always visible schema')] class Actor extends Entity{} ``` -------------------------------- ### JSON collection response sample Source: https://mixerapi.com/plugins/collection-view Example JSON response for a collection request (e.g., /films). Shows pagination metadata under 'collection' and data under 'data'. ```json { "collection": { "url": "/films?page=3&direction=desc", "count": 20, "total": 1000, "pages": 50, "next": "/films?page=4", "prev": "/films?page=2", "first": "/films", "last": "/films?page=50" }, "data": [ { "id": 1, "first_name": "PENELOPE", "last_name": "GUINESS", "modified": "2006-02-15T04:34:33+00:00", "films": [ { "id": 1, "title": "ACADEMY DINOSAUR", "description": "A Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies", "release_year": "2006", "language_id": 1, "rental_duration": 6, "length": 86, "rating": "PG", "special_features": "Deleted Scenes,Behind the Scenes", "modified": "2006-02-15T05:03:42+00:00" } ] } ] } ``` -------------------------------- ### Load RequestHandler component in AppController Source: https://mixerapi.com/plugins/collection-view Required setup: your controllers must use the RequestHandler component, typically loaded in AppController::initialize(). ```php # src/Controller/AppController.php public function initialize(): void { parent::initialize(); $this->loadComponent('RequestHandler'); // other logic... } ``` -------------------------------- ### OpenApiRequestBody OpenAPI Output Source: https://mixerapi.com/plugins/cakephp-swagger-bake/docs/attributes The resulting OpenAPI specification generated from the OpenApiRequestBody attribute example. ```yaml requestBody: content: application/json: schema: $ref: '#/components/schema/Custom' ``` -------------------------------- ### Manually serialize data with JsonSerializer Source: https://mixerapi.com/plugins/hal-view Demonstrates how to use JsonSerializer to convert data into JSON or array formats, including an example with pagination support. ```php use MixerApi\HalView\JsonSerializer; # json $json = (new JsonSerializer($data))->asJson(JSON_PRETTY_PRINT); // asJson argument is optional # array $hal = (new JsonSerializer($data))->getData(); # json with `_links.self.href` and pagination meta data use Cake\Http\ServerRequest; use Cake\View\Helper\PaginatorHelper; $json = (new JsonSerializer($data, new ServerRequest(), new PaginatorHelper()))->asJson(); ``` -------------------------------- ### OpenApiQueryParam Attribute Usage Source: https://mixerapi.com/plugins/cakephp-swagger-bake/docs/attributes Example of applying the OpenApiQueryParam attribute to a controller action to define query parameters. ```php #[OpenApiQueryParam(name: "option", isRequired: true, enum: ["A","B","C"], description: "desc...")] #[OpenApiQueryParam(ref: "#/x-my-project/components/parameters/my-parameter")] public function index() {} ``` -------------------------------- ### OpenAPI Schema Property Output Source: https://mixerapi.com/plugins/cakephp-swagger-bake/docs/attributes The resulting OpenAPI YAML representation for the properties defined in the Employee entity example. ```yaml example_one: type: string minLength: 5 maxLength: 10 example_two: type: string enum: - PG - R required: true example_virtual_field: type: string readOnly: true ``` -------------------------------- ### OpenApiRequestBody Attribute Usage Source: https://mixerapi.com/plugins/cakephp-swagger-bake/docs/attributes Example of applying the OpenApiRequestBody attribute to a controller action to describe the request body. ```php #[OpenApiRequestBody(ref: '#/components/schema/Custom', ignoreCakeSchema: true, mimeTypes: ['application/json'])] public function index() {} ``` -------------------------------- ### Defining OpenApiResponse with multiple mimeTypes and status codes Source: https://mixerapi.com/plugins/cakephp-swagger-bake/docs/attributes Example of defining multiple mime types and status codes for a controller action. ```php #[OpenApiResponse( statusCode: '40x', ref: '#/components/schemas/Exception', mimeTypes: ['application/xml','application/json'] )] #[OpenApiResponse(schemaType: 'array', ref: '#/components/schemas/Actor')] public function index(){} ``` -------------------------------- ### Manually load MixerApi/Bake plugin in Application.php Source: https://mixerapi.com/plugins/bake Manually load the MixerApi/Bake plugin in your Application's bootstrap method after installing it via Composer. This is an alternative to using the plugin loader command. ```php # src/Application.php public function bootstrap(): void { // other logic... $this->addPlugin('MixerApi/Bake'); } ``` -------------------------------- ### Custom exception JSON output Source: https://mixerapi.com/plugins/exception-render Example JSON output for a custom exception like InventoryExceededException, showing the exception name, message, URL, and HTTP 500 code. ```json { "exception": "InventoryExceededException", "message": "No inventory exists", "url": "/requested-url", "code": 500 } ``` -------------------------------- ### Implement OpenApiExceptionSchemaInterface for custom exception schema Source: https://mixerapi.com/plugins/cakephp-swagger-bake Example exception class implementing OpenApiExceptionSchemaInterface. getExceptionCode returns the HTTP status code, getExceptionDescription returns an optional description (null omits it), and getExceptionSchema returns the schema definition. ```php class MyException implements OpenApiExceptionSchemaInterface { public static function getExceptionCode(): string { return '400'; } public static function getExceptionDescription(): ?string { return 'An optional description'; // returning null omits the response description } public static function getExceptionSchema(): Schema|string { return (new \SwaggerBake\Lib\OpenApi\Schema()) ->setTitle('MyException') ->setProperties([ (new SchemaProperty())->setType('string')->setName('code')->setExample('400'), (new SchemaProperty())->setType('string')->setName('message')->setExample('error'), (new SchemaProperty())->setType('string')->setName('wherever')->setExample('whatever you want') ]); } } ``` -------------------------------- ### ValidationException JSON output Source: https://mixerapi.com/plugins/exception-render Example JSON output when a ValidationException is thrown, showing the exception details, message, URL, HTTP 422 code, and violations array with property paths and messages. ```json { "exception": "ValidationException", "message": "Error saving resource `Actor`", "url": "/actors", "code": 422, "violations": [ { "propertyPath": "first_name", "messages": [ { "rule": "_required", "message": "This field is required" } ] }, { "propertyPath": "last_name", "messages": [ { "rule": "_required", "message": "This field is required" } ] } ] } ``` -------------------------------- ### Controller action with validation exception handling Source: https://mixerapi.com/plugins/exception-render Example controller action that uses newEmptyEntity() and patchEntity() to merge request data, potentially throwing a ValidationException. The action saves the entity and serializes it, or throws a generic exception on failure. ```php public function add() { $this->request->allowMethod('post'); $actor = $this->Actors->newEmptyEntity(); $actor = $this->Actors->patchEntity($actor, $this->request->getData()); // potential ValidationException here if ($this->Actors->save($actor)) { $this->viewBuilder()->setOption('serialize', 'actor'); $this->set('actor', $actor); return; } throw new \Exception("Record failed to save"); } ``` -------------------------------- ### OpenApiDtoQuery attribute examples and OpenAPI output Source: https://mixerapi.com/plugins/cakephp-swagger-bake/docs/attributes Shows OpenApiDtoQuery usage in a DTO property and with constructor property promotion, plus the resulting OpenAPI query parameter. The attribute is deprecated in favor of OpenApiQueryParam in v2.4.4+. ```php class ActorDto { #[OpenApiDtoQuery(name: 'genre', isRequired: true, enum: ['action','horror'])] private string $genre; ``` ```php class ActorDto { public function __construct( #[OpenApiDtoQuery(name: 'genre', isRequired: true, enum: ['action','horror'])] private string $genre ) { } ``` ```yaml get: parameters: - in: query name: genre required: true schema: type: string enum: - action - horror ``` -------------------------------- ### Load Configuration in bootstrap.php Source: https://mixerapi.com/plugins/jwt-auth Load the configuration file into your application. ```php # in config/bootstrap.php Configure::load('mixerapi_jwtauth'); ``` -------------------------------- ### Create routes with --prefix option Source: https://mixerapi.com/plugins/rest Specify a prefix for the generated routes using the --prefix option. ```bash bin/cake mixerapi:rest route create --prefix /api ``` -------------------------------- ### SwaggerBake Configuration Array Source: https://mixerapi.com/plugins/cakephp-swagger-bake/assets/swagger_bake.php A sample configuration array for SwaggerBake, demonstrating how to set paths, hot-reloading, and optional settings. ```php return [ 'SwaggerBake' => [ 'prefix' => '/your-relative-api-url', 'yml' => '/config/swagger.yml', 'json' => '/webroot/swagger.json', 'webPath' => '/swagger.json', 'hotReload' => Configure::read('debug'), 'jsonOptions' => Configure::read('debug') ? JSON_PRETTY_PRINT : JSON_UNESCAPED_UNICODE, /* 'editActionMethods' => ['PATCH'], 'requestAccepts' => [ 'application/json', 'application/x-www-form-urlencoded', 'application/xml', ], 'responseContentTypes' => [ 'application/json', 'application/xml', 'application/hal+json', 'application/json+ld' ], 'docType' => 'swagger', 'exceptionSchema' => 'Exception', 'namespaces' => [ 'controllers' => ['\App\\'], 'entities' => ['\App\\'], 'tables' => ['\App\\'] ], */ ] ]; ``` -------------------------------- ### Create routes for a plugin with --plugin option Source: https://mixerapi.com/plugins/rest Generate routes for a specific plugin using the --plugin option. ```bash # writes to `plugins/MyPlugin/config/routes.php` bin/cake mixerapi:rest route create --plugin MyPlugin ``` -------------------------------- ### JWT Payload Example Source: https://mixerapi.com/plugins/jwt-auth Example JWT payload generated by the login controller. Contains issuer, subject, audience, expiration, JWT ID, and user data. ```json { "iss": "mixerapi", "sub": "5e28e9ed-f3e1-4eb2-aa88-8d618f4021ee", "aud": "api-client", "exp": 1651972707, "jti": "a1f6f5ec-748d-4a1c-9d0e-f8e19ec7f9b2", "user": { "email": "test@example.com" } } ``` -------------------------------- ### Run PHPUnit Test Suite Source: https://mixerapi.com/plugins/cakephp-swagger-bake Execute the project's PHPUnit test suite using Composer. ```bash composer test ``` -------------------------------- ### Manually load the plugin in Application.php Source: https://mixerapi.com/plugins/hal-view Alternatively, add the plugin to the bootstrap method in your Application class. ```php # src/Application.php public function bootstrap(): void { // other logic... $this->addPlugin('MixerApi/HalView'); } ``` -------------------------------- ### Initialize Custom SwaggerController for Plugin Source: https://mixerapi.com/plugins/cakephp-swagger-bake Configure a custom controller to load plugin-specific SwaggerBake settings. The third argument in Configure::load must be false to prevent overwriting the main application configuration. ```php public function initialize(): void { parent::initialize(); Configure::load('OtherApi.swagger_bake', 'default', false); // note: `false` for the third argument is important /* * Only load the component if you are using a version older than v2.3.0. This component will be deprecated * in v3.0.0 */ $this->loadComponent('SwaggerBake.SwaggerUi'); } ``` -------------------------------- ### Initialize GrumPHP Source: https://mixerapi.com/plugins/cakephp-swagger-bake Initialize GrumPHP to enable pre-commit hooks for tests and static analysis. ```bash composer grumphp-init ``` -------------------------------- ### Bake a single controller with MixerApi/Bake theme Source: https://mixerapi.com/plugins/bake Bake a single controller with the MixerApi/Bake theme. Replace {ControllerName} with the actual controller name. ```bash bin/cake bake controller {ControllerName} --theme MixerApi/Bake ``` -------------------------------- ### Run Static Analysis and Code Quality Tools Source: https://mixerapi.com/plugins/cakephp-swagger-bake Run PHPUnit, PHPCS, PHPSTAN, and PHPMD to analyze the codebase. ```bash composer analyze ``` -------------------------------- ### Display Swagger Models Source: https://mixerapi.com/plugins/cakephp-swagger-bake List all models currently recognized by SwaggerBake. ```bash bin/cake swagger models ``` -------------------------------- ### Generate Swagger Schema for Plugin Source: https://mixerapi.com/plugins/cakephp-swagger-bake Run the bake command specifying the custom configuration file for the plugin. ```bash bin/cake swagger bake --config OtherApi.swagger_bake ``` -------------------------------- ### Dry-run route creation with --display option Source: https://mixerapi.com/plugins/rest Perform a dry-run of route creation without writing to the file using the --display option. ```bash bin/cake mixerapi:rest route create --display ``` -------------------------------- ### Bake everything with MixerApi/Bake theme Source: https://mixerapi.com/plugins/bake Bake everything with the MixerApi/Bake theme. The theme only impacts controllers. ```bash bin/cake bake all --everything --theme MixerApi/Bake ``` -------------------------------- ### Initialize Swagger with SwaggerBake.initialize Source: https://mixerapi.com/plugins/cakephp-swagger-bake/docs/events Dispatched before SwaggerBake begins building the OpenAPI documentation, allowing modification of the Swagger object. ```php EventManager::instance() ->on('SwaggerBake.initialize', function (Event $event) { /** @var \SwaggerBake\Lib\Swagger $swagger */ $swagger = $event->getSubject(); $array = $swagger->getArray(); $array['title'] = 'A new title'; $swagger->setArray($array); }); ``` -------------------------------- ### Configure response key names in config/collection_view.php Source: https://mixerapi.com/plugins/collection-view Optional configuration to rename response keys. Create config/collection_view.php and map new keys to the original placeholders like {{collection}} and {{data}}. Keep the mapped items as-is. ```php # config/collection_view.php return [ 'CollectionView' => [ 'pagination' => '{{collection}}', // array that holds pagination data 'pagination.url' => '{{url}}', // url of current page 'pagination.count' => '{{count}}', // items on the page 'pagination.total' => '{{total}}', // total database records 'pagination.pages' => '{{pages}}', // total pages 'pagination.next' => '{{next}}', // next page url 'pagination.prev' => '{{prev}}', // previous page url 'pagination.first' => '{{first}}', // first page url 'pagination.last' => '{{last}}', // last page url 'items' => '{{data}}', // the collection of data ] ]; ``` -------------------------------- ### Catching ValidationException with try-catch Source: https://mixerapi.com/plugins/exception-render Example of catching a ValidationException thrown by patchEntity() to perform additional logic, using the MixerApi\ExceptionRender\ValidationException class. ```php try { $actor = $this->Actors->newEmptyEntity(); $actor = $this->Actors->patchEntity($actor, $this->request->getData()); } catch (\MixerApi\ExceptionRender\ValidationException $e) { // do something here } ``` -------------------------------- ### Enable jsonld route extension Source: https://mixerapi.com/plugins/json-ld-view Optionally enable the jsonld extension to request JSON-LD by extension, e.g., /index.jsonld. ```php # config/routes.php $routes->scope('/', function (RouteBuilder $builder) { $builder->setExtensions(['jsonld']); // ... other code }); ``` -------------------------------- ### MethodNotAllowedException JSON output Source: https://mixerapi.com/plugins/exception-render Example JSON output for a MethodNotAllowedException, showing the exception name, message, URL, and HTTP 405 code. ```json { "exception": "MethodNotAllowedException", "message": "Your exception message here", "url": "/actors", "code": 405 } ``` -------------------------------- ### Create with save options Source: https://mixerapi.com/plugins/crud Passes options to save(), such as making the password field accessible. Use when you need to customize the save operation. ```php return $create->save($this, [ 'accessibleFields' => [ 'password' => true, ] ]); ``` -------------------------------- ### Manually load MixerAPI in Application.php Source: https://mixerapi.com/install Alternatively, you can manually register the plugin in your src/Application.php file. ```php # src/Application.php public function bootstrap(): void { // other logic... $this->addPlugin('MixerApi'); } ``` -------------------------------- ### Display Swagger Routes Source: https://mixerapi.com/plugins/cakephp-swagger-bake List all routes currently recognized by SwaggerBake. ```bash bin/cake swagger routes ``` -------------------------------- ### Read with options Source: https://mixerapi.com/plugins/crud Passes options to read(), such as containing associated tables. Note the source uses save() instead of read() here. ```php return $read->save($this, ['contains' => ['OtherTable']]); ``` -------------------------------- ### Load Swagger Bake Configuration Source: https://mixerapi.com/plugins/cakephp-swagger-bake Load the configuration file in your config/bootstrap.php. ```php Configure::load('swagger_bake', 'default', false); ``` -------------------------------- ### Bake all controllers with MixerApi/Bake theme Source: https://mixerapi.com/plugins/bake Bake all controllers using the MixerApi/Bake theme. The theme is required to apply the API-focused template. ```bash bin/cake bake controller all --theme MixerApi/Bake ``` -------------------------------- ### Generate OpenAPI JSON from command line Source: https://mixerapi.com/plugins/cakephp-swagger-bake Run this command to generate OpenAPI JSON at any time. ```bash bin/cake swagger bake ``` -------------------------------- ### HAL collection response with pagination Source: https://mixerapi.com/plugins/hal-view Example HAL collection response with pagination links and embedded actors. Note the missing comma after the modified field in the actor object, as in the source. ```json { "_links": { "self": { "href": "/actors?page=3" }, "next": { "href": "/actors?page=4" }, "prev": { "href": "/actors?page=2" }, "first": { "href": "/actors?page=1" }, "last": { "href": "/actors?page=11" } }, "count": 20, "total": 207, "_embedded": { "actors": [ { "id": 1, "first_name": "PENELOPE", "last_name": "GUINESS", "modified": "2006-02-15T04:34:33+00:00" "_embedded": { "films": [ { "id": 1, "title": "ACADEMY DINOSAUR", "description": "A Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies", "release_year": "2006", "language_id": 1, "rental_duration": 6, "rental_rate": "0.99", "length": 86, "replacement_cost": "20.99", "rating": "PG", "special_features": "Deleted Scenes,Behind the Scenes", "modified": "2006-02-15T05:03:42+00:00" } ] } } ] } } ``` -------------------------------- ### HAL response for actor 149 Source: https://mixerapi.com/plugins/hal-view Example HAL response for a single actor with embedded films. Note the missing comma after the modified field in the film object, which is present in the source. ```json { "_links": { "self": { "href": "/actors/149" } }, "id": 149, "first_name": "RUSSELL", "last_name": "TEMPLE", "modified": "2006-02-15T04:34:33+00:00", "_embedded": { "films": [ { "id": 53, "title": "BANG KWAI", "description": "A Epic Drama of a Madman And a Cat who must Face a A Shark in An Abandoned Amusement Park", "release_year": "2006", "language_id": 1, "rental_duration": 5, "rental_rate": "2.99", "length": 87, "replacement_cost": "25.99", "rating": "NC-17", "special_features": "Deleted Scenes,Behind the Scenes", "modified": "2006-02-15T05:03:42+00:00" "_links": { "self": { "href": "/films/53" } } } ] } } ``` -------------------------------- ### Register MixerApi/Crud in Application.php Source: https://mixerapi.com/plugins/crud Add the Crud plugin to your application during the bootstrap process. ```php # src/Application.php public function bootstrap(): void { $this->addPlugin('MixerApi/Crud', $options); } ``` -------------------------------- ### Add contexts and vocab routes Source: https://mixerapi.com/plugins/json-ld-view Define routes for the contexts and vocab endpoints. The contexts route displays JSON-LD schema for an entity, while the vocab route shows all entities and additional metadata. ```php # config/routes.php $routes->scope('/', function (RouteBuilder $builder) { $builder->connect('/contexts/*', [ 'plugin' => 'MixerApi/JsonLdView', 'controller' => 'JsonLd', 'action' => 'contexts' ]); $builder->connect('/vocab', [ 'plugin' => 'MixerApi/JsonLdView', 'controller' => 'JsonLd', 'action' => 'vocab' ]); // ... other code }); ``` -------------------------------- ### List routes for a specific plugin or main app Source: https://mixerapi.com/plugins/rest Limit route listing to a specific plugin or the main application using the --plugin option. ```bash # limit to a plugin: bin/cake mixerapi:rest route list --plugin MyPlugin #limit to main application: bin/cake mixerapi:rest route list --plugin App ``` -------------------------------- ### Event listener for beforeRender to customize error messages Source: https://mixerapi.com/plugins/exception-render Example event listener class that implements EventListenerInterface and listens to the 'MixerApi.ExceptionRender.beforeRender' event to modify viewVars and serialize variables via ErrorDecorator. It checks for UnauthenticatedException and sets a custom message. ```php 'beforeRender' ]; } /** * @param \Cake\Event\Event $event */ public function beforeRender(\Cake\Event\Event $event) { $errorDecorator = $event->getSubject(); $data = $event->getData(); if (!$errorDecorator instanceof ErrorDecorator || !$data['exception'] instanceof MixerApiExceptionRenderer) { return; } if (!$data['exception']->getError() instanceof \Authentication\Authenticator\UnauthenticatedException) { return; } $viewVars = $errorDecorator->getViewVars(); $viewVars['message'] = 'A custom unauthenticated message'; $errorDecorator->setViewVars($viewVars); } } ``` -------------------------------- ### Sample vocab JSON-LD response at /vocab Source: https://mixerapi.com/plugins/json-ld-view Sample vocab response for entities implementing JsonLdDataInterface, shown when browsing to the vocab route (e.g., `/vocab`). Includes the `@contexts` definition and a `supportedClass` entry for Language. ```json { "@contexts": { "@vocab": "/vocab", "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", "rdfs": "http://www.w3.org/2000/01/rdf-schema#", "xmls": "http://www.w3.org/2001/XMLSchema#", "owl": "http://www.w3.org/2002/07/owl#", "schema": "http://schema.org" }, "@id": "/vocab", "@type": "ApiDocumentation", "title": "API Documentation", "description": "", "supportedClass": [ { "@id": "https://schema.org/Language", "@type": "Class", "title": "Language", "supportedProperty": [ { "@type": "supportedProperty", "property": { "@id": "https://schema.org/name", "@type": "rdf:Property", "rdfs:label": "name", "domain": "https://schema.org/Language", "range": "xmls:char" }, "title": "name", "required": false, "readable": true, "writeable": true, "description": "" } ] } // ...and other items ] } ```