### Create New Laravel Project with JSON:API Tutorial Setup Source: https://laraveljsonapi.io/3.x/tutorial This command downloads and executes a script to set up a new Laravel project specifically configured for the JSON:API tutorial. It assumes Docker is installed and running. ```bash curl -s https://laravel.build/jsonapi-tutorial | bash ``` -------------------------------- ### Install Laravel JSON:API Testing Package Source: https://laraveljsonapi.io/3.x/testing Installs the testing package for Laravel JSON:API using Composer. This package provides helpers for constructing test JSON:API requests and asserting JSON:API content in test responses. ```bash composer require --dev laravel-json-api/testing ``` -------------------------------- ### Start Laravel Sail Application Source: https://laraveljsonapi.io/3.x/tutorial After creating the project, this command navigates into the project directory and starts the application using Laravel Sail, which manages the Docker environment. It's used to run the application locally. ```bash cd jsonapi-tutorial && ./vendor/bin/sail up ``` -------------------------------- ### Install Laravel JSON:API Package Source: https://laraveljsonapi.io/3.x/getting-started Installs the main Laravel JSON:API package and its testing utilities using Composer. The testing package is recommended as a development dependency. ```Bash composer require laravel-json-api/laravel composer require --dev laravel-json-api/testing ``` -------------------------------- ### Check Laravel Artisan Version Source: https://laraveljsonapi.io/3.x/tutorial This command verifies that the Artisan command-line interface is working correctly within the Laravel project managed by Sail. It outputs the installed Laravel framework version. ```bash vendor/bin/sail artisan -V ``` -------------------------------- ### Example API Request for Enumerable Pagination Source: https://laraveljsonapi.io/3.x/digging-deeper/non-eloquent An example HTTP GET request demonstrating how to request a specific page and page size using query parameters for enumerable pagination. ```http GET /api/v1/sites?page[number]=1&page[size]=25 Accept: application/vnd.api+json ``` -------------------------------- ### Publish Laravel JSON:API Configuration Source: https://laraveljsonapi.io/3.x/getting-started Publishes the package's configuration file to your Laravel project using an Artisan command. This creates a `config/jsonapi.php` file. ```Bash php artisan vendor:publish --provider="LaravelJsonApi\Laravel\ServiceProvider" ``` -------------------------------- ### Example Request with Custom Cursor Parameters Source: https://laraveljsonapi.io/3.x/schemas/pagination An example HTTP GET request demonstrating the use of custom parameter names ('size', 'starting-after') for cursor-based pagination. ```http GET /api/v1/posts?page[size]=25&page[starting-after]=df093f2d-f042-49b0-af77-195625119773 HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Example HTTP Request with Query Parameters Source: https://laraveljsonapi.io/3.x/testing/requests Provides an example of an HTTP GET request demonstrating how query parameters like 'include' and 'page' are formatted in a JSON:API request. ```http GET /api/v1/posts?include=author,tags&page[number]=1&page[size]=10 HTTP/1.1 Accept: application/vnd.api+json ``` ```http GET /api/v1/posts?include=author,tags HTTP/1.1 Accept: application/vnd.api+json ``` ```http GET /api/v1/posts?fields[posts]=title,slug,author&fields[users]=name HTTP/1.1 Accept: application/vnd.api+json ``` ```http GET /api/v1/posts?filter[published]=true HTTP/1.1 Accept: application/vnd.api+json ``` ```http GET /api/v1/posts?sort=-publishedAt,title HTTP/1.1 Accept: application/vnd.api+json ``` ```http GET /api/v1/posts?page[number]=1&page[size]=10 HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### HTTP POST Request Example Source: https://laraveljsonapi.io/3.x/digging-deeper/non-eloquent An example of an HTTP POST request to create a new 'sites' resource, demonstrating the expected headers and content type for a JSON:API request. ```http POST /api/v1/sites HTTP/1.1 Accept: application/vnd.api+json Content-Type: application/vnd.api+json { //... } ``` -------------------------------- ### Example Page-Based Pagination Request Source: https://laraveljsonapi.io/3.x/schemas/pagination This is an example HTTP GET request demonstrating how a client would request a specific page and size of resources using the 'page[number]' and 'page[size]' query parameters. ```http GET /api/v1/posts?page[number]=2&page[size]=15 HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Make JSON:API Test Request and Assert Response Source: https://laraveljsonapi.io/3.x/testing Demonstrates how to use the `jsonApi` method from the `MakesJsonApiRequests` trait to initiate a JSON:API request and assert the fetched resource. It includes specifying the expected resource type, include paths, and using `assertFetchedOneExact` for assertion. ```php public function test(): void { $expected = // ... our expected posts resource object. $response = $this ->jsonApi() ->expects('posts') ->includePaths('author', 'tags') ->get('/api/v1/posts'); $response->assertFetchedOneExact($expected); } ``` -------------------------------- ### Example API Request with Cursor Pagination Source: https://laraveljsonapi.io/3.x/schemas/pagination An example HTTP GET request to fetch posts using cursor-based pagination with 'after' and 'limit' parameters. ```http GET /api/v1/posts?page[limit]=10&page[after]=03ea3065-fe1f-476a-ade1-f16b40c19140 HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Install Laravel JSON:API Package Source: https://laraveljsonapi.io/3.x/tutorial/03-server-and-schemas Installs the main Laravel JSON:API package and the testing package using Composer via Sail. This is the initial step for integrating the library into a Laravel application. ```bash vendor/bin/sail composer require laravel-json-api/laravel vendor/bin/sail composer require --dev laravel-json-api/testing ``` -------------------------------- ### Install Cursor Pagination Package Source: https://laraveljsonapi.io/3.x/schemas/pagination Installs the cursor pagination extension for Laravel JSON:API using Composer. ```bash composer require laravel-json-api/cursor-pagination ``` -------------------------------- ### Create Post Request Example Source: https://laraveljsonapi.io/3.x/tutorial/05-creating-resources An example of a POST request to create a new post resource, including author and tags relationships, adhering to the JSON:API specification. ```http POST http://localhost/api/v1/posts?include=author,tags HTTP/1.1 Accept: application/vnd.api+json Content-Type: application/vnd.api+json { "data": { "type": "posts", "attributes": { "content": "In our second blog post, you will learn how to create resources using the JSON:API specification.", "publishedAt": null, "slug": "creating-jsonapi-resources", "title": "How to Create JSON:API Resources" }, "relationships": { "tags": { "data": [ { "type": "tags", "id": "2" } ] } } } } ``` -------------------------------- ### Install Laravel JSON:API Boolean Soft Deletes (Bash) Source: https://laraveljsonapi.io/3.x/schemas/soft-deleting Provides the Composer command to install the `laravel-json-api/boolean-softdeletes` package, which enables support for the tenantcloud/laravel-boolean-softdeletes package. ```bash composer require laravel-json-api/boolean-softdeletes ``` -------------------------------- ### Configure Exception Handler for JSON:API Errors Source: https://laraveljsonapi.io/3.x/getting-started Updates the application's exception handler to correctly render JSON:API error responses. It involves adding `JsonApiException` to the `$dontReport` property and registering the package's exception renderer. ```PHP namespace App\Exceptions; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use LaravelJsonApi\Core\Exceptions\JsonApiException; class Handler extends ExceptionHandler { // ... /** * A list of the exception types that should not be reported. * * @var array */ protected $dontReport = [ JsonApiException::class, ]; /** * Register the exception handling callbacks for the application. * * @return void */ public function register() { $this->renderable( \LaravelJsonApi\Exceptions\ExceptionParser::make()->renderable() ); } } ``` -------------------------------- ### Example JSON:API Response with Sparse Fieldsets Source: https://laraveljsonapi.io/3.x/tutorial/08-fetching-resources This is an example of a successful JSON:API response when using sparse fieldsets. It includes meta information about pagination, JSON:API version, links for navigation, and the requested data for posts, with only the specified fields and included author relationship. ```JSON HTTP/1.1 200 OK Content-Type: application/vnd.api+json { "meta": { "page": { "currentPage": 1, "from": 1, "lastPage": 16, "perPage": 5, "to": 5, "total": 76 } }, "jsonapi": { "version": "1.0" }, "links": { "first": "http:\/\/localhost\/api\/v1\/posts?include=author&page%5Bnumber%5D=1&page%5Bsize%5D=5", "last": "http:\/\/localhost\/api\/v1\/posts?include=author&page%5Bnumber%5D=16&page%5Bsize%5D=5", "next": "http:\/\/localhost\/api\/v1\/posts?include=author&page%5Bnumber%5D=2&page%5Bsize%5D=5" }, "data": [ { "type": "posts", "id": "1", "attributes": { "publishedAt": "2021-11-04T17:30:52.000000Z", "title": "Welcome to Laravel JSON:API" }, "relationships": { "author": { "links": { "related": "http:\/\/localhost\/api\/v1\/posts\/1\/author", "self": "http:\/\/localhost\/api\/v1\/posts\/1\/relationships\/author" }, "data": { "type": "users", "id": "1" } } }, "links": { "self": "http:\/\/localhost\/api\/v1\/posts\/1" } }, { "type": "posts", "id": "3", "attributes": { "publishedAt": "1994-04-23T14:16:56.000000Z", "title": "sed impedit error et non" }, "relationships": { "author": { "links": { "related": "http:\/\/localhost\/api\/v1\/posts\/3\/author", "self": "http:\/\/localhost\/api\/v1\/posts\/3\/relationships\/author" }, "data": { "type": "users", "id": "6" } } }, "links": { "self": "http:\/\/localhost\/api\/v1\/posts\/3" } }, { "type": "posts", "id": "5", "attributes": { "publishedAt": "1993-01-18T02:55:30.000000Z", "title": "repudiandae impedit et facere sint" }, "relationships": { "author": { "links": { "related": "http:\/\/localhost\/api\/v1\/posts\/5\/author", "self": "http:\/\/localhost\/api\/v1\/posts\/5\/relationships\/author" }, "data": { "type": "users", "id": "4" } } }, "links": { "self": "http:\/\/localhost\/api\/v1\/posts\/5" } }, { "type": "posts", "id": "7", "attributes": { "publishedAt": "1985-07-15T01:17:17.000000Z", "title": "omnis est quis atque ipsum" }, "relationships": { "author": { "links": { "related": "http:\/\/localhost\/api\/v1\/posts\/7\/author", "self": "http:\/\/localhost\/api\/v1\/posts\/7\/relationships\/author" }, "data": { "type": "users", "id": "3" } } }, "links": { "self": "http:\/\/localhost\/api\/v1\/posts\/7" } }, { "type": "posts", "id": "9", "attributes": { "publishedAt": "1984-05-29T14:26:49.000000Z", "title": "earum provident sit tenetur sint" }, "relationships": { "author": { "links": { "related": "http:\/\/localhost\/api\/v1\/posts\/9\/author", "self": "http:\/\/localhost\/api\/v1\/posts\/9\/relationships\/author" }, "data": { "type": "users", "id": "6" } } }, "links": { "self": "http:\/\/localhost\/api\/v1\/posts\/9" } } ], "included": [ { "type": "users", "id": "1", ``` -------------------------------- ### Example Request for Related Resource (HTTP) Source: https://laraveljsonapi.io/3.x/requests/query-parameters An example HTTP request demonstrating the pattern for viewing a related resource, specifically the author of a post. ```HTTP GET /api/v1/posts/123/author HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Test API Request for Post Resource Source: https://laraveljsonapi.io/3.x/tutorial/03-server-and-schemas An example HTTP request to fetch a specific post resource from the API. This demonstrates how to make a GET request to the API endpoint after authorization logic is in place. ```http GET http://localhost/api/v1/posts/1 HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Example API Response with Cursor Pagination Meta Source: https://laraveljsonapi.io/3.x/schemas/pagination An example HTTP response containing metadata for cursor-based pagination, including 'from', 'hasMore', 'perPage', and 'to' cursors, along with pagination links. ```http HTTP/1.1 200 OK Content-Type: application/vnd.api+json { "meta": { "page": { "from": "bfdaa836-68a3-4427-8ea3-2108dd48d4d3", "hasMore": true, "perPage": 10, "to": "df093f2d-f042-49b0-af77-195625119773" } }, "links": { "first": "http://localhost/api/v1/posts?page[limit]=10", "prev": "http://localhost/api/v1/posts?page[limit]=10&page[before]=bfdaa836-68a3-4427-8ea3-2108dd48d4d3", "next": "http://localhost/api/v1/posts?page[limit]=10&page[after]=df093f2d-f042-49b0-af77-195625119773" }, "data": [...] } ``` -------------------------------- ### Fetch Posts (HTTP GET Request) Source: https://laraveljsonapi.io/3.x/tutorial/08-fetching-resources Demonstrates an HTTP GET request to fetch all posts from the /api/v1/posts endpoint. It includes the necessary headers for JSON:API content. ```http GET http://localhost/api/v1/posts HTTP/1.1 Content-Type: application/vnd.api+json ``` -------------------------------- ### Install laravel-json-api/non-eloquent (Bash) Source: https://laraveljsonapi.io/3.x/digging-deeper/non-eloquent This bash command installs the `laravel-json-api/non-eloquent` package into your Laravel application using Composer. This package enables the use of custom, non-Eloquent models with Laravel JSON:API. ```bash composer require laravel-json-api/non-eloquent ``` -------------------------------- ### Install Laravel JSON:API Hashids Package Source: https://laraveljsonapi.io/3.x/schemas/identifier Installs the `laravel-json-api/hashids` package and publishes the configuration for the `vinkla/hashids` package. These commands are necessary to enable the use of hash IDs for obscuring primary keys. ```bash composer require laravel-json-api/hashids php artisan vendor:publish --provider="Vinkla\Hashids\HashidsServiceProvider" ``` -------------------------------- ### Request Posts by Multiple IDs using Filter Source: https://laraveljsonapi.io/3.x/tutorial/08-fetching-resources This HTTP request example demonstrates how a client can filter posts by providing multiple IDs in the `filter[id][]` query parameter. It shows the correct format for the GET request, including the `Accept` header for JSON:API compliance. ```http GET http://localhost/api/v1/posts?filter[id][]=1&filter[id][]=3&filter[id][]=5 HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Example Request for Relationship Data (HTTP) Source: https://laraveljsonapi.io/3.x/requests/query-parameters An example HTTP request illustrating the pattern for viewing relationship data, specifically the tags relationship of a post. ```HTTP GET /api/v1/posts/123/relationships/tags HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### PHP CrudSiteRelations Capability Implementation Source: https://laraveljsonapi.io/3.x/digging-deeper/non-eloquent Example of a PHP class (`CrudSiteRelations`) extending `CrudRelations` to manage resource relationships. It demonstrates constructor dependency injection for `SiteStorage`. ```php namespace App\JsonApi\Sites\Capabilities; use App\Entities\SiteStorage; use LaravelJsonApi\NonEloquent\Capabilities\CrudRelations; class CrudSiteRelations extends CrudRelations { /** * @var SiteStorage */ private SiteStorage $storage; /** * ModifySiteRelationships constructor. * * @param SiteStorage $storage */ public function __construct(SiteStorage $storage) { parent::__construct(); $this->storage = $storage; } } ``` -------------------------------- ### Fetch All Posts After Seeding (HTTP GET Request) Source: https://laraveljsonapi.io/3.x/tutorial/08-fetching-resources An HTTP GET request to fetch all posts after the database has been seeded. This demonstrates retrieving multiple resources from the API. ```http GET http://localhost/api/v1/posts HTTP/1.1 Content-Type: application/vnd.api+json ``` -------------------------------- ### Basic Proxy Schema Definition (PHP) Source: https://laraveljsonapi.io/3.x/digging-deeper/proxies Example of a basic proxy schema for a `user-accounts` resource, extending `ProxySchema` and specifying the proxy model. ```php namespace App\JsonApi\V1\UserAccounts; use App\JsonApi\Proxies\UserAccount; use LaravelJsonApi\Eloquent\Contracts\Paginator; use LaravelJsonApi\Eloquent\Fields\DateTime; use LaravelJsonApi\Eloquent\Fields\ID; use LaravelJsonApi\Eloquent\Filters\WhereIn; use LaravelJsonApi\Eloquent\Pagination\PagePagination; use LaravelJsonApi\Eloquent\ProxySchema; class UserAccountSchema extends ProxySchema { /** * The model the schema corresponds to. * * @var string */ public static string $model = UserAccount::class; /** * Get the resource fields. * * @return array */ public function fields(): array { return [ ID::make(), DateTime::make('createdAt')->sortable()->readOnly(), DateTime::make('updatedAt')->sortable()->readOnly(), ]; } /** * Get the resource filters. * * @return array */ public function filters(): array { return [ WhereIn::make('id', $this->idColumn()), ]; } /** * Get the resource paginator. * * @return Paginator|null */ public function pagination(): ?Paginator { return PagePagination::make(); } } ``` -------------------------------- ### Store Action: Created Hook Example (PHP) Source: https://laraveljsonapi.io/3.x/routing/controllers Provides an example of the 'created' hook for the 'Store' action, called exclusively after a resource is created. It receives the created model, request, and query parameters. ```php use App\JsonApi\V1\Posts\PostQuery; use App\JsonApi\V1\Posts\PostRequest; use App\Models\Post; public function created(Post $post, PostRequest $request, PostQuery $query): void { // do something only on created... } ``` -------------------------------- ### Example Page-Based Pagination Response Source: https://laraveljsonapi.io/3.x/schemas/pagination This is an example HTTP response for a paged request, including meta information about the current page, total pages, and links for navigation (first, last, next, prev). ```http HTTP/1.1 200 OK Content-Type: application/vnd.api+json { "meta": { "page": { "currentPage": 2, "from": 16, "lastPage": 4, "perPage": 15, "to": 30, "total": 50 } }, "links": { "first": "http://localhost/api/v1/posts?page[number]=1&page[size]=15", "last": "http://localhost/api/v1/posts?page[number]=4&page[size]=15", "next": "http://localhost/api/v1/posts?page[number]=3&page[size]=15", "prev": "http://localhost/api/v1/posts?page[number]=1&page[size]=15" }, "data": [...] ``` -------------------------------- ### Example JSON:API Controller Structure Source: https://laraveljsonapi.io/3.x/routing/controllers An example of a controller generated by `jsonapi:controller`. It utilizes traits for various JSON:API actions like fetching, storing, updating, and deleting resources, as well as managing relationships. ```php namespace App\Http\Controllers\Api\V1; use App\Http\Controllers\Controller; use LaravelJsonApi\Laravel\Http\Controllers\Actions; class PostController extends Controller { use Actions\FetchMany; use Actions\FetchOne; use Actions\Store; use Actions\Update; use Actions\Destroy; use Actions\FetchRelated; use Actions\FetchRelationship; use Actions\UpdateRelationship; use Actions\AttachRelationship; use Actions\DetachRelationship; } ``` -------------------------------- ### Registering Proxy Resource Routes (PHP) Source: https://laraveljsonapi.io/3.x/digging-deeper/proxies Example of how to register routes for both standard and proxy resources within a Laravel JSON:API server. ```php use LaravelJsonApi\Laravel\Http\Controllers\JsonApiController; JsonApiRoute::server('v1') ->prefix('v1') ->resources(function ($server) { $server->resource('users', JsonApiController::class); $server->resources('user-accounts', JsonApiController::class); }); ``` -------------------------------- ### Example GET Request with Page Number Source: https://laraveljsonapi.io/3.x/schemas/pagination An example HTTP GET request demonstrating how a client might request a specific page number, omitting the page size. ```HTTP GET /api/v1/posts?page[number]=1 HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Laravel JSON:API Directory Structure Example Source: https://laraveljsonapi.io/3.x/getting-started/directory-structure Illustrates the recommended file and directory layout for a Laravel JSON:API server, including controllers, schemas, requests, and resources for 'posts' and 'users' resources. ```bash ├── app | ├── Http | | ├── Controllers | | | ├── Api | | | | ├── V1 | | | | | ├── PostController.php | | | | | ├── UserController.php | ├── JsonApi | | ├── Filters | | | ├── CustomFilter | | ├── V1 | | | ├── Posts | | | | ├── PostCollectionQuery.php (optional) | | | | ├── PostQuery.php (optional) | | | | ├── PostRequest.php (required if writable) | | | | ├── PostResource.php (optional) | | | | ├── PostSchema.php | | | ├── Users | | | | ├── UserSchema.php | | | ├── Server.php ``` -------------------------------- ### Populate Database with PostSeeder Source: https://laraveljsonapi.io/3.x/tutorial/02-models Defines the `run` method within `PostSeeder.php` to create initial data, including users, tags, posts, and comments, associating them as needed. ```php namespace Database\Seeders; use App\Models\Comment; use App\Models\Post; use App\Models\Tag; use App\Models\User; use Illuminate\Database\Seeder; class PostSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { $author = User::create([ 'name' => 'Artie Shaw', 'email' => 'artie.shaw@jsonapi-tutorial.test', 'password' => bcrypt('password'), 'email_verified_at' => now(), ]); $commenter = User::create([ 'name' => 'Benny Goodman', 'email' => 'benny.goodman@jsonapi-tutorial.test', 'password' => bcrypt('password'), 'email_verified_at' => now(), ]); $tag1 = Tag::create(['name' => 'Laravel']); $tag2 = Tag::create(['name' => 'JSON:API']); $post = new Post([ 'title' => 'Welcome to Laravel JSON:API', 'published_at' => now(), 'content' => 'In our first blog post, you will learn all about Laravel JSON:API...', 'slug' => 'welcome-to-laravel-jsonapi', ]); $post->author()->associate($author)->save(); $post->tags()->saveMany([$tag1, $tag2]); $comment = new Comment([ 'content' => 'Wow! Great first blog article. Looking forward to more!', ]); $comment->post()->associate($post); $comment->user()->associate($commenter)->save(); } } ``` -------------------------------- ### Run Database Seeding Command Source: https://laraveljsonapi.io/3.x/tutorial/02-models Executes the database seeding process using the Artisan command-line tool, which will run all registered seeders, including the `PostSeeder`. ```bash vendor/bin/sail artisan db:seed ``` -------------------------------- ### HTTP Request for Reading Relations (HTTP) Source: https://laraveljsonapi.io/3.x/digging-deeper/non-eloquent Example HTTP GET requests to retrieve a resource's relationship or relationship data. ```http GET /api/v1/sites// HTTP/1.1 Accept: application/vnd.api+json ``` ```http GET /api/v1/sites//relationships/ HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Fetch Media Relationship Endpoint Source: https://laraveljsonapi.io/3.x/digging-deeper/polymorphic-to-many Example of a GET request to fetch the 'media' relationship endpoint for a specific post. ```http GET /api/v1/posts/1/media HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Run Database Seed Command (Bash) Source: https://laraveljsonapi.io/3.x/tutorial/08-fetching-resources Artisan command to execute the database seeders, specifically the PostsSeeder class, to populate the database with user and post data. ```bash vendor/bin/sail artisan db:seed --class PostsSeeder ``` -------------------------------- ### Include Media Relationship Source: https://laraveljsonapi.io/3.x/digging-deeper/polymorphic-to-many Example of how to include the 'media' relationship in a GET request to fetch posts, demonstrating eager loading. ```http GET /api/v1/posts/1?include=media HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Create PostSeeder File Source: https://laraveljsonapi.io/3.x/tutorial/02-models Generates a new seeder file named `PostSeeder.php` in the `/database/seeders` directory using the Artisan command-line tool. ```bash vendor/bin/sail artisan make:seeder PostSeeder ``` -------------------------------- ### HTTP: Exclude Resources by Category Source: https://laraveljsonapi.io/3.x/schemas/filters An example HTTP GET request demonstrating how a client can exclude posts by specifying multiple values for the 'not-category' filter. ```http GET /api/v1/posts?filter[not-category]=foo&filter[not-category]=bar HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Filter Resource by Slug Source: https://laraveljsonapi.io/3.x/schemas/filters Example HTTP GET request to filter posts by the 'slug' parameter. This shows how a client would utilize the defined filters. ```http GET /api/v1/posts?filter[slug]=hello-world HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Implement QueryAll Capability for Sites Source: https://laraveljsonapi.io/3.x/digging-deeper/non-eloquent This PHP code demonstrates how to create a custom capability class `QuerySites` that extends `LaravelJsonApiNonEloquentCapabilitiesQueryAll`. It includes a constructor to inject a `SiteStorage` dependency and implements the `get()` method to retrieve all sites. ```php namespace App\JsonApi\V1\Sites\Capabilities; use App\Entities\SiteStorage; use LaravelJsonApi\NonEloquent\Capabilities\QueryAll; class QuerySites extends QueryAll { /** * @var SiteStorage */ private SiteStorage $sites; /** * QuerySites constructor. * * @param SiteStorage $sites */ public function __construct(SiteStorage $sites) { parent::__construct(); $this->sites = $sites; } /** * @inheritDoc */ public function get(): iterable { return $this->sites->all(); } } ``` -------------------------------- ### HTTP: Exclude Resources with Delimited IDs Source: https://laraveljsonapi.io/3.x/schemas/filters An example HTTP GET request demonstrating the exclusion of posts using a comma-separated string of IDs when `WhereIdNotIn` is configured with a delimiter. ```http GET /api/v1/posts?filter[exclude]=3,9 HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Integrate QueryAll Capability into SiteRepository Source: https://laraveljsonapi.io/3.x/digging-deeper/non-eloquent This PHP code shows how to integrate the `QuerySites` capability into the `SiteRepository`. It involves implementing the `LaravelJsonApi\Contracts\Store\QueriesAll` interface and returning an instance of the `QuerySites` capability from the `queryAll()` method. ```php namespace App\JsonApi\V1\Sites; use LaravelJsonApi\Contracts\Store\QueriesAll; use LaravelJsonApi\NonEloquent\AbstractRepository; class SiteRepository extends AbstractRepository implements QueriesAll { // ... /** * @inheritDoc */ public function queryAll(): Capabilities\QuerySites { return Capabilities\QuerySites::make() ->withServer($this->server()) ->withSchema($this->schema()); } } ``` -------------------------------- ### Filter Relationship by Slug Source: https://laraveljsonapi.io/3.x/schemas/filters Example HTTP GET request to filter posts associated with a specific user by their 'slug'. This demonstrates using schema filters on relationship endpoints. ```http GET /api/v1/users/123/posts?filter[slug]=hello-world HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Create Post Factory Command (Bash) Source: https://laraveljsonapi.io/3.x/tutorial/08-fetching-resources Artisan command to generate a new PostFactory class file in the database/factories directory. This factory will be used to create Post model instances. ```bash vendor/bin/sail artisan make:factory PostFactory ``` -------------------------------- ### Requesting a Post Resource with Relationships Source: https://laraveljsonapi.io/3.x/tutorial/04-relationships This example demonstrates an HTTP GET request to retrieve a specific post resource, including its relationships, using the `Accept` header for JSON:API. ```HTTP GET http://localhost/api/v1/posts/1 HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Create Posts Seeder Command (Bash) Source: https://laraveljsonapi.io/3.x/tutorial/08-fetching-resources Artisan command to generate a new PostsSeeder class file in the database/seeders directory. This seeder will be responsible for populating the database with Post records using the PostFactory. ```bash vendor/bin/sail artisan make:seed PostsSeeder ``` -------------------------------- ### HTTP: Request Resources with Delimited Categories Source: https://laraveljsonapi.io/3.x/schemas/filters An example HTTP GET request showing how to request posts using a comma-separated string of categories when the `WhereIn` filter is configured with a delimiter. ```http GET /api/v1/posts?filter[category]=foo,bar HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### HTTP: Request Resources by Category Source: https://laraveljsonapi.io/3.x/schemas/filters An example HTTP GET request showing how a client can request posts belonging to specific categories using multiple `filter[category]` parameters. ```http GET /api/v1/posts?filter[category]=foo&filter[category]=bar HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### HTTP: Exclude Resources by ID Source: https://laraveljsonapi.io/3.x/schemas/filters An example HTTP GET request illustrating how a client can exclude specific posts by providing an array of IDs in the `filter[exclude]` query parameter. ```http GET /api/v1/posts?filter[exclude][]=3&filter[exclude][]=9 HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Implement create() Method in CrudSite (PHP) Source: https://laraveljsonapi.io/3.x/digging-deeper/non-eloquent Provides an example implementation of the `create()` method within the `CrudSite` class. This method handles the creation of a new 'Site' entity, including setting relationships using `toOne()` and `toMany()` helper methods. ```php namespace App\JsonApi\V1\Sites\Capabilities; use App\Entities\Site; use LaravelJsonApi\NonEloquent\Capabilities\CrudResource; class CrudSite extends CrudResource { // ... /** * Create a new site. * * @param array $validatedData * @return Site */ public function create(array $validatedData): Site { $owner = $this->toOne($validatedData['owner'] ?? null); $tags = $this->toMany($validatedData['tags'] ?? []); $site = new Site($validatedData['slug']); $site->setDomain($validatedData['domain'] ?? null); $site->setName($validatedData['name'] ?? null); $site->setOwner($owner); $site->setTags(...$tags); $this->storage->store($site); return $site; } } ``` -------------------------------- ### Filter Pivot Relationship by Approved Status Source: https://laraveljsonapi.io/3.x/schemas/filters Example HTTP GET request to filter roles for a user based on the 'approved' pivot attribute. This demonstrates using pivot filters. ```http GET /api/v1/users/123/roles?filter[approved]=true HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Generate Authentication Token with Tinker Source: https://laraveljsonapi.io/3.x/tutorial/05-creating-resources This bash command sequence demonstrates how to use Laravel's Tinker to find a user, generate a token for them, and retrieve the plain text token. This token is then used to authenticate API requests. ```Bash vendor/bin/sail artisan tinker >>> $user = User::find(1); >>> $token = $user->createToken('Test'); >>> $token->plainTextToken => "1|dl21xEBuPevtoMzi0Yy1eQhrV91ENvoJypFDAHdt" >>> exit ``` -------------------------------- ### HTTP: Request Resources with Delimited IDs Source: https://laraveljsonapi.io/3.x/schemas/filters An example HTTP GET request showing how a client can request posts using a comma-separated string of IDs when the `WhereIdIn` filter is configured with a delimiter. ```http GET /api/v1/posts?filter[id]=3,9 HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### HTTP: Request Multiple Resources by ID Source: https://laraveljsonapi.io/3.x/schemas/filters An example HTTP GET request demonstrating how a client can request multiple posts by specifying an array of IDs in the `filter[id]` query parameter. ```http GET /api/v1/posts?filter[id][]=3&filter[id][]=9 HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Create `DataResponse` Instance Source: https://laraveljsonapi.io/3.x/responses Shows two ways to create a `DataResponse` instance for returning resource data. The first uses the constructor, and the second uses the static `make` method to allow chaining of helper methods like `withHeader` and `withMeta`. ```php use LaravelJsonApi.Core.Responses.DataResponse; return new DataResponse($model); // or return DataResponse::make($model) ->withHeader('X-Foo', 'Bar') ->withMeta(['foo' => 'bar']); ``` -------------------------------- ### HTTP Request for Posts Source: https://laraveljsonapi.io/3.x/schemas/pagination An example HTTP GET request to fetch 'posts' resources without any pagination parameters. This scenario highlights the need for forcing pagination to avoid large responses. ```http GET /api/v1/posts HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Example Custom Page Parameter Request Source: https://laraveljsonapi.io/3.x/schemas/pagination This HTTP GET request shows how a client would use custom page parameters ('page[page]' and 'page[limit]') after customization in the schema. ```http GET /api/v1/posts?page[page]=2&page[limit]=15 HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Add MakesJsonApiRequests Trait to TestCase Source: https://laraveljsonapi.io/3.x/testing Adds the `MakesJsonApiRequests` trait to your application's base TestCase class. This trait provides methods for making JSON:API requests within your tests. ```php namespace Tests; use Illuminate\Foundation\Testing\TestCase as BaseTestCase; use LaravelJsonApi\Testing\MakesJsonApiRequests; abstract class TestCase extends BaseTestCase { use CreatesApplication; use MakesJsonApiRequests; } ``` -------------------------------- ### Register JSON:API Server in Config (PHP) Source: https://laraveljsonapi.io/3.x/tutorial/03-server-and-schemas Configuration snippet for `config/jsonapi.php` showing how to register a JSON:API server. It includes the root namespace and a list of servers, with the 'v1' server uncommented for activation. ```php return [ /* |-------------------------------------------------------------------------- | Root Namespace |-------------------------------------------------------------------------- | | The root JSON:API namespace, within your application's namespace. | This is used when generating any class that does not sit *within* | a server's namespace. For example, new servers and filters. | | By default this is set to `JsonApi` which means the root namespace | will be `\App\JsonApi`, if your application's namespace is `App`. */ 'namespace' => 'JsonApi', /* |-------------------------------------------------------------------------- | Servers |-------------------------------------------------------------------------- | | A list of the JSON:API compliant APIs in your application, referred to | as "servers". They must be listed below, with the array key being the | unique name for each server, and the value being the fully-qualified | class name of the server class. */ 'servers' => [ // 'v1' => \App\JsonApi\V1\Server::class, ], ]; ``` ```php 'servers' => [ 'v1' => \App\JsonApi\V1\Server::class, ], ``` -------------------------------- ### Implement Create Resource Interface (PHP) Source: https://laraveljsonapi.io/3.x/digging-deeper/non-eloquent Updates the `SiteRepository` to implement the `CreatesResources` interface, signifying its ability to handle resource creation requests. ```php namespace App\JsonApi\V1\Sites; use LaravelJsonApi\Contracts\Store\CreatesResources; use LaravelJsonApi\NonEloquent\AbstractRepository; use LaravelJsonApi\NonEloquent\Concerns\HasCrudCapability; class SiteRepository extends AbstractRepository implements CreatesResources { use HasCrudCapability; // ... } ``` -------------------------------- ### Register 'me' Action for Users Source: https://laraveljsonapi.io/3.x/routing/custom-actions Shows how to register a 'me' GET action for a 'users' resource without a prefix. This example highlights the importance of ensuring the action name does not conflict with the resource ID pattern. ```php $server->resource('users')->actions(function (ActionRegistrar $actions) { $actions->get('me'); }); ``` -------------------------------- ### Generate Laravel Models and Migrations Source: https://laraveljsonapi.io/3.x/tutorial/02-models This snippet shows the bash commands to generate Eloquent models for Post, Tag, and Comment, along with their corresponding database migrations using Laravel's Artisan command-line tool. ```bash vendor/bin/sail artisan make:model Post --migration vendor/bin/sail artisan make:model Tag --migration vendor/bin/sail artisan make:model Comment --migration ``` -------------------------------- ### Get Post Tags (GET) Source: https://laraveljsonapi.io/3.x/tutorial/06-modifying-resources Retrieves the list of tags currently associated with a specific post. This is done via a GET request to the post's tags endpoint. ```http GET http://localhost/api/v1/posts/2/tags Authorization: Bearer Accept: application/vnd.api+json ``` -------------------------------- ### Run Laravel Migrations (Bash) Source: https://laraveljsonapi.io/3.x/tutorial/02-models This command executes all pending database migrations in a Laravel project using Sail. It's essential for creating or updating database tables based on migration files. ```bash vendor/bin/sail artisan migrate ``` -------------------------------- ### Call PostSeeder from DatabaseSeeder Source: https://laraveljsonapi.io/3.x/tutorial/02-models Integrates the `PostSeeder` into the main `DatabaseSeeder.php` file by calling it within the `run` method, ensuring it's executed during the seeding process. ```php namespace Database\Seeders; use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { /** * Seed the application's database. * * @return void */ public function run() { $this->call(PostSeeder::class); } } ``` -------------------------------- ### HTTP DELETE Request Example Source: https://laraveljsonapi.io/3.x/digging-deeper/non-eloquent Example of an HTTP DELETE request to remove a resource using the JSON:API specification. It specifies the endpoint and the expected Accept header. ```http DELETE /api/v1/sites/ HTTP/1.1 Accept: application/vnd.api+json ``` -------------------------------- ### Generate JSON:API Server (Bash) Source: https://laraveljsonapi.io/3.x/tutorial/03-server-and-schemas Command to create a new JSON:API server instance named 'v1' in a Laravel application using the `jsonapi:server` artisan command. ```bash vendor/bin/sail artisan jsonapi:server v1 ``` -------------------------------- ### Generate Post Collection Query File in Bash Source: https://laraveljsonapi.io/3.x/tutorial/08-fetching-resources This command generates the `PostCollectionQuery.php` file using the Laravel JSON:API artisan command, which is the starting point for defining query parameter validation rules. ```bash vendor/bin/sail artisan jsonapi:query posts --collection ``` -------------------------------- ### Initial Laravel API Routes Source: https://laraveljsonapi.io/3.x/tutorial/03-server-and-schemas Shows the default content of a Laravel `routes/api.php` file before adding JSON:API routes. It includes a basic route for handling authenticated user requests. ```php use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; /* |-------------------------------------------------------------------------- | API Routes |-------------------------------------------------------------------------- | | Here is where you can register API routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | is assigned the "api" middleware group. Enjoy building your API! | */ Route::middleware('auth:sanctum')->get('/user', function (Request $request) { return $request->user(); }); ``` -------------------------------- ### Generate JSON:API Resource Source: https://laraveljsonapi.io/3.x/resources Generates a resource class for a given resource type using the `jsonapi:resource` Artisan command. The `--server` option specifies the server to associate the resource with, which is optional if only one server is configured. ```bash php artisan jsonapi:resource posts --server=v1 ``` -------------------------------- ### Example: Detaching Relationship Request (HTTP) Source: https://laraveljsonapi.io/3.x/requests/resources An example HTTP request showing the method for detaching resources from a 'to-many' relationship. This corresponds to the `isDetachingRelationship` functionality. ```HTTP DELETE /api/v1/posts/123/relationships/tags HTTP/1.1 Content-Type: application/vnd.api+json Accept: application/vnd.api+json { ... } ```