{"id":914,"date":"2023-08-15T22:35:15","date_gmt":"2023-08-15T22:35:15","guid":{"rendered":"https:\/\/www.w3computing.com\/articles\/?p=914"},"modified":"2023-08-23T16:20:20","modified_gmt":"2023-08-23T16:20:20","slug":"building-restful-api-laravel","status":"publish","type":"post","link":"https:\/\/www.w3computing.com\/articles\/building-restful-api-laravel\/","title":{"rendered":"Building a RESTful API with Laravel"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Overview of RESTful APIs<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Representational State Transfer (REST) is an architectural style that defines a set of constraints and properties based on HTTP. RESTful APIs are designed to handle the creation, reading, updating, and deletion (CRUD) of resources, which are represented in a textual format like JSON.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Key Principles:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Statelessness:<\/strong> Each request from a client to a server must contain all the information needed to understand and process the request.<\/li>\n\n\n\n<li><strong>Client-Server Architecture:<\/strong> The client and server are independent of each other, allowing each to be developed and enhanced separately.<\/li>\n\n\n\n<li><strong>Uniform Interface:<\/strong> RESTful APIs use standard HTTP methods like GET, POST, PUT, DELETE, making it easy to understand and interact with the API.<\/li>\n\n\n\n<li><strong>Resource-Based:<\/strong> Resources are the key abstractions in RESTful APIs, and they can be accessed and manipulated using standard HTTP methods.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The benefits of using RESTful APIs include scalability, simplicity, performance, and the ability to use standard HTTP methods. They have become a popular choice for building web services, enabling different applications to communicate with each other seamlessly.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Introduction to Laravel<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Laravel is a powerful and elegant PHP framework designed for web application development. It offers various tools and features tailored for building modern and robust applications, including APIs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Features in Context of API Development:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Eloquent ORM:<\/strong> Provides an advanced implementation of the active record pattern, making it easier to interact with the database using object-oriented syntax.<\/li>\n\n\n\n<li><strong>Routing System:<\/strong> Laravel&#8217;s routing system allows for easy creation of RESTful routes.<\/li>\n\n\n\n<li><strong>Middleware:<\/strong> Use middleware to filter HTTP requests entering your application, e.g., for authentication and CORS.<\/li>\n\n\n\n<li><strong>Dependency Injection &amp; IOC Container:<\/strong> Makes it easy to manage dependencies and adhere to SOLID principles.<\/li>\n\n\n\n<li><strong>Validation &amp; Error Handling:<\/strong> Laravel offers robust validation and error handling out of the box, easing the development process.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Laravel has become a popular choice among developers for building RESTful APIs due to its elegant syntax and comprehensive ecosystem.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What You&#8217;ll Build<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In this guide, we will build a RESTful API for a fictional Bookstore. This API will allow users to perform CRUD operations on resources like books, authors, and categories. The application will include features such as authentication, validation, pagination, and error handling.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The example is designed to be relatable to most readers and will provide a real-world context for understanding how to create a RESTful API using Laravel. Along the way, we will delve into various Laravel features and best practices, crafting an API that&#8217;s scalable, maintainable, and aligned with industry standards.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Setting Up the Development Environment<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Installing Laravel<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Laravel provides a straightforward installation process. First, make sure you have PHP, Composer, and necessary extensions installed on your system. Then follow these steps:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Install Laravel Installer<\/strong> (optional but recommended):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">composer global require laravel\/installer<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\"><strong>Create a New Laravel Project:<\/strong> If you installed the Laravel Installer:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">laravel <span class=\"hljs-keyword\">new<\/span> bookstore-api<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Alternatively, you can use Composer directly:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">composer create-project --prefer-dist laravel\/laravel bookstore-api<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\"><strong>Navigate to Your Project:<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\"><span class=\"hljs-built_in\">cd<\/span> bookstore-api<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\"><strong>Start Development Server:<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">php artisan serve<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This will create a new Laravel project named <code><strong>bookstore-api<\/strong><\/code> and start a development server at <code><strong>http:\/\/127.0.0.1:8000<\/strong><\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Setting Up a Database<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Laravel supports various databases like MySQL, PostgreSQL, SQLite, and more. Here&#8217;s how you can set up a MySQL database:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Create a Database in MySQL:<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"SQL (Structured Query Language)\" data-shcb-language-slug=\"sql\"><span><code class=\"hljs language-sql\"><span class=\"hljs-keyword\">CREATE<\/span> <span class=\"hljs-keyword\">DATABASE<\/span> bookstore;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">SQL (Structured Query Language)<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">sql<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\"><strong>Configure <code>.env<\/code> File:<\/strong> Open the <code><strong>.env<\/strong><\/code> file in your Laravel project and update the following lines with your database credentials:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">DB_CONNECTION=mysql\r\nDB_HOST=127.0.0.1\r\nDB_PORT=3306\r\nDB_DATABASE=bookstore\r\nDB_USERNAME=root\r\nDB_PASSWORD=your_password<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\"><strong>Run Migrations:<\/strong> Laravel&#8217;s migration system allows you to create and modify tables in the database:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">php artisan migrate<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Dependencies and Tools<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Laravel comes with a rich set of tools and dependencies that make development easier:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Eloquent ORM:<\/strong> Allows interacting with the database using an object-oriented syntax.<\/li>\n\n\n\n<li><strong>Artisan Console:<\/strong> A command-line tool that helps in managing various Laravel tasks.<\/li>\n\n\n\n<li><strong>Blade Templating Engine:<\/strong> Though not required for an API project, it&#8217;s worth mentioning for web development.<\/li>\n\n\n\n<li><strong>PHPUnit:<\/strong> Laravel is configured with PHPUnit for testing out-of-the-box.<\/li>\n\n\n\n<li><strong>Laravel Passport\/Sanctum:<\/strong> Choose between these packages for handling API authentication (to be discussed later in the guide).<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">You may also want to install additional dependencies based on your specific needs. For example, you may use Postman for API testing or Docker for containerization.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Designing the API<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Planning Endpoints<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Designing the endpoints in advance helps in structuring the API and making development smoother. For our Bookstore API, we can define the following endpoints to perform CRUD operations on books, authors, and categories:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Books:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>GET<\/strong> <code>\/api\/books<\/code>: Retrieve all books.<\/li>\n\n\n\n<li><strong>GET<\/strong> <code>\/api\/books\/{id}<\/code>: Retrieve a specific book by ID.<\/li>\n\n\n\n<li><strong>POST<\/strong> <code>\/api\/books<\/code>: Create a new book.<\/li>\n\n\n\n<li><strong>PUT<\/strong> <code>\/api\/books\/{id}<\/code>: Update a specific book by ID.<\/li>\n\n\n\n<li><strong>DELETE<\/strong> <code>\/api\/books\/{id}<\/code>: Delete a specific book by ID.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Authors:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>GET<\/strong> <code>\/api\/authors<\/code>: Retrieve all authors.<\/li>\n\n\n\n<li><strong>GET<\/strong> <code>\/api\/authors\/{id}<\/code>: Retrieve a specific author by ID.<\/li>\n\n\n\n<li><strong>POST<\/strong> <code>\/api\/authors<\/code>: Create a new author.<\/li>\n\n\n\n<li><strong>PUT<\/strong> <code>\/api\/authors\/{id}<\/code>: Update a specific author by ID.<\/li>\n\n\n\n<li><strong>DELETE<\/strong> <code>\/api\/authors\/{id}<\/code>: Delete a specific author by ID.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Categories:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Similar endpoints can be defined for categories.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">These endpoints adhere to the RESTful principles, utilizing standard HTTP methods and maintaining a clear and consistent structure.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Authentication<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Authentication is essential for protecting sensitive endpoints and ensuring that only authorized users can perform certain actions. Laravel offers several built-in solutions for API authentication, such as Passport and Sanctum.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Laravel Passport:<\/strong> Passport is a full OAuth2 server implementation, making it ideal for applications that need to offer personal access tokens, OAuth2 authorization codes, and more. To install Passport, you can run:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">composer require laravel\/passport\r\nphp artisan migrate\r\nphp artisan passport:install<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Then, you&#8217;ll need to modify your <code><strong>User<\/strong><\/code> model and authentication configuration to use Passport.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Laravel Sanctum:<\/strong> For simpler applications that don&#8217;t require full OAuth2 compliance, Sanctum provides a lightweight solution to handle token-based authentication. To install Sanctum, run:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">composer require laravel\/sanctum\r\nphp artisan vendor:publish --provider=<span class=\"hljs-string\">\"Laravel\\Sanctum\\SanctumServiceProvider\"<\/span>\r\nphp artisan migrate<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">You&#8217;ll then need to modify the <code><strong>User<\/strong><\/code> model and set up Sanctum&#8217;s middleware.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Both Passport and Sanctum offer robust solutions to secure your API, with Passport offering more advanced features, and Sanctum being more streamlined for SPA or mobile applications.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Building the API<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Creating Models and Migrations<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In Laravel, Eloquent models serve as the query builder for the database, and migrations are like version control for your database. Let&#8217;s start with creating a model for Books.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">php artisan make:model Book -m<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This command generates both a model and a migration file. You can define the schema in the migration file as:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">up<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n    Schema::create(<span class=\"hljs-string\">'books'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">(Blueprint $table)<\/span> <\/span>{\r\n        $table-&gt;id();\r\n        $table-&gt;string(<span class=\"hljs-string\">'title'<\/span>);\r\n        $table-&gt;text(<span class=\"hljs-string\">'description'<\/span>);\r\n        $table-&gt;timestamps();\r\n    });\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Then, run the migrations:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">php artisan migrate<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Repeat this process for other entities like authors and categories.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Defining Controllers<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Controllers handle the logic behind each endpoint. For the Book model, you can create a controller:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">php artisan make:controller BookController --resource<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The <code><strong>--resource<\/strong><\/code> flag generates a controller with methods corresponding to RESTful actions. You can then define logic for each action:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">index<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n    <span class=\"hljs-keyword\">return<\/span> Book::all();\r\n}\r\n\r\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">store<\/span><span class=\"hljs-params\">(Request $request)<\/span>\r\n<\/span>{\r\n    <span class=\"hljs-keyword\">return<\/span> Book::create($request-&gt;all());\r\n}\r\n\r\n<span class=\"hljs-comment\">\/\/ Other methods...<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Implementing Middleware<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Middleware provides a way to filter requests entering the application. Laravel comes with several middleware, such as authentication, CORS, and logging. To create custom middleware:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">php artisan make:middleware CustomMiddleware<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Then, you can define the logic inside the <code><strong>handle<\/strong><\/code> method and register the middleware within the <code><strong>Kernel.php<\/strong><\/code> file.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Validation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Laravel&#8217;s validation mechanisms enable you to ensure that incoming data adheres to specified rules. In the BookController, for example, you can validate incoming data as follows:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">store<\/span><span class=\"hljs-params\">(Request $request)<\/span>\r\n<\/span>{\r\n    $request-&gt;validate(&#91;\r\n        <span class=\"hljs-string\">'title'<\/span> =&gt; <span class=\"hljs-string\">'required|max:255'<\/span>,\r\n        <span class=\"hljs-string\">'description'<\/span> =&gt; <span class=\"hljs-string\">'required'<\/span>,\r\n    ]);\r\n\r\n    <span class=\"hljs-keyword\">return<\/span> Book::create($request-&gt;all());\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This ensures that both the title and description are present, and the title doesn&#8217;t exceed 255 characters.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Writing Routes<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Laravel&#8217;s routing system allows you to map endpoints to controllers. In the <code><strong>routes\/api.php<\/strong><\/code> file, you can define the routes for the Book model:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">Route::resource(<span class=\"hljs-string\">'books'<\/span>, <span class=\"hljs-string\">'BookController'<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This single line will handle all the CRUD operations for the books, routing them to the appropriate methods in the BookController.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Authentication &amp; Authorization<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">User Registration &amp; Login<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Handling user registration and login is an essential part of building a secure API. In Laravel, this process can be streamlined using built-in functionalities.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First, you can create a <code><strong>UserController<\/strong><\/code> to handle user-related actions:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">php artisan make:controller UserController<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">For user registration, you might define a method like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">register<\/span><span class=\"hljs-params\">(Request $request)<\/span>\r\n<\/span>{\r\n    $request-&gt;validate(&#91;\r\n        <span class=\"hljs-string\">'name'<\/span> =&gt; <span class=\"hljs-string\">'required'<\/span>,\r\n        <span class=\"hljs-string\">'email'<\/span> =&gt; <span class=\"hljs-string\">'required|email|unique:users'<\/span>,\r\n        <span class=\"hljs-string\">'password'<\/span> =&gt; <span class=\"hljs-string\">'required|min:8'<\/span>,\r\n    ]);\r\n\r\n    $user = User::create(&#91;\r\n        <span class=\"hljs-string\">'name'<\/span> =&gt; $request-&gt;name,\r\n        <span class=\"hljs-string\">'email'<\/span> =&gt; $request-&gt;email,\r\n        <span class=\"hljs-string\">'password'<\/span> =&gt; bcrypt($request-&gt;password),\r\n    ]);\r\n\r\n    <span class=\"hljs-keyword\">return<\/span> response()-&gt;json(&#91;<span class=\"hljs-string\">'message'<\/span> =&gt; <span class=\"hljs-string\">'User registered successfully!'<\/span>], <span class=\"hljs-number\">201<\/span>);\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">For login, Laravel offers various packages like Passport or Sanctum. Using Passport, for example, the login method might look like:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-21\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">login<\/span><span class=\"hljs-params\">(Request $request)<\/span>\r\n<\/span>{\r\n    $request-&gt;validate(&#91;\r\n        <span class=\"hljs-string\">'email'<\/span> =&gt; <span class=\"hljs-string\">'required|email'<\/span>,\r\n        <span class=\"hljs-string\">'password'<\/span> =&gt; <span class=\"hljs-string\">'required'<\/span>,\r\n    ]);\r\n\r\n    <span class=\"hljs-keyword\">if<\/span> (Auth::attempt($request-&gt;only(<span class=\"hljs-string\">'email'<\/span>, <span class=\"hljs-string\">'password'<\/span>))) {\r\n        <span class=\"hljs-keyword\">return<\/span> response()-&gt;json(Auth::user()-&gt;createToken(<span class=\"hljs-string\">'authToken'<\/span>)-&gt;accessToken);\r\n    }\r\n\r\n    <span class=\"hljs-keyword\">return<\/span> response()-&gt;json(&#91;<span class=\"hljs-string\">'error'<\/span> =&gt; <span class=\"hljs-string\">'Invalid credentials'<\/span>], <span class=\"hljs-number\">401<\/span>);\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-21\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This login method validates the request, attempts to authenticate the user, and then generates an access token using Passport.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Access Control<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">For implementing authorization policies, Laravel&#8217;s Gate and Policy classes are useful tools to define what actions a user can perform.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, you can define a policy for the Book model to determine who can update or delete a book. In the <code><strong>BookPolicy<\/strong><\/code> class, you might have:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-22\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">update<\/span><span class=\"hljs-params\">(User $user, Book $book)<\/span>\r\n<\/span>{\r\n    <span class=\"hljs-keyword\">return<\/span> $user-&gt;id === $book-&gt;user_id;\r\n}\r\n\r\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">delete<\/span><span class=\"hljs-params\">(User $user, Book $book)<\/span>\r\n<\/span>{\r\n    <span class=\"hljs-keyword\">return<\/span> $user-&gt;id === $book-&gt;user_id || $user-&gt;isAdmin();\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-22\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">You can register this policy in the <code><strong>AuthServiceProvider<\/strong><\/code> class:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-23\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">protected<\/span> $policies = &#91;\r\n    Book::class =&gt; BookPolicy::class,\r\n];<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-23\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Then, in the <code><strong>BookController<\/strong><\/code>, you can authorize actions using the <code><strong>authorize<\/strong><\/code> method:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-24\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">update<\/span><span class=\"hljs-params\">(Request $request, Book $book)<\/span>\r\n<\/span>{\r\n    <span class=\"hljs-keyword\">$this<\/span>-&gt;authorize(<span class=\"hljs-string\">'update'<\/span>, $book);\r\n\r\n    <span class=\"hljs-comment\">\/\/ Update logic...<\/span>\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-24\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">By utilizing Laravel&#8217;s built-in authentication and authorization features, developers can efficiently handle user registration, login, and access control, ensuring that the API remains secure and that users can only perform actions they are allowed to do.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Testing the API<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Testing is a crucial part of the development process, ensuring that the API behaves as expected. Laravel comes with robust testing support, leveraging PHPUnit, and provides convenient methods to make requests to your application and examine their output.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Writing Test Cases<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Laravel provides different types of tests like Feature Tests and Unit Tests. In the context of an API, feature tests are particularly valuable to test the HTTP endpoints.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s how you might write a feature test for the Book model.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Creating a Test:<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">First, create a new test case:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-25\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">php artisan make:<span class=\"hljs-built_in\">test<\/span> BookTest<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-25\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h4 class=\"wp-block-heading\">Setting Up the Test:<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">You can use Laravel\u2019s built-in methods to set up the test, such as creating models or authenticating users. For example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-26\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">App<\/span>\\<span class=\"hljs-title\">Models<\/span>\\<span class=\"hljs-title\">Book<\/span>;\r\n\r\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">test_can_retrieve_books<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n    $book = Book::factory()-&gt;create();\r\n\r\n    $response = <span class=\"hljs-keyword\">$this<\/span>-&gt;get(<span class=\"hljs-string\">'\/api\/books'<\/span>);\r\n\r\n    $response-&gt;assertStatus(<span class=\"hljs-number\">200<\/span>)\r\n             -&gt;assertJson(&#91;$book-&gt;toArray()]);\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-26\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h4 class=\"wp-block-heading\">Testing Different Scenarios:<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">You can also test different scenarios like creating, updating, or deleting resources. For example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-27\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">test_can_create_book<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n    $data = &#91;\r\n        <span class=\"hljs-string\">'title'<\/span> =&gt; <span class=\"hljs-string\">'Sample Book'<\/span>,\r\n        <span class=\"hljs-string\">'description'<\/span> =&gt; <span class=\"hljs-string\">'A sample book description'<\/span>,\r\n    ];\r\n\r\n    $response = <span class=\"hljs-keyword\">$this<\/span>-&gt;post(<span class=\"hljs-string\">'\/api\/books'<\/span>, $data);\r\n\r\n    $response-&gt;assertStatus(<span class=\"hljs-number\">201<\/span>)\r\n             -&gt;assertJson($data);\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-27\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h4 class=\"wp-block-heading\">Running the Tests:<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">To run your tests, you can use the following command:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-28\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">php artisan <span class=\"hljs-built_in\">test<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-28\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h4 class=\"wp-block-heading\">Authentication and Authorization Testing:<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Laravel provides methods to handle authenticated tests as well. If you have endpoints that require authentication, you can write tests to ensure that unauthorized access is restricted.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Testing Validation Rules:<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Testing validation rules ensures that invalid data doesn\u2019t get processed. For instance:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-29\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">test_title_is_required_to_create_book<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n    $response = <span class=\"hljs-keyword\">$this<\/span>-&gt;post(<span class=\"hljs-string\">'\/api\/books'<\/span>, &#91;<span class=\"hljs-string\">'description'<\/span> =&gt; <span class=\"hljs-string\">'Description only'<\/span>]);\r\n\r\n    $response-&gt;assertStatus(<span class=\"hljs-number\">422<\/span>)\r\n             -&gt;assertJsonValidationErrors(<span class=\"hljs-string\">'title'<\/span>);\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-29\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Testing the API with Laravel means employing its expressive and fluent interface to write tests that cover a wide range of scenarios. By ensuring that all endpoints and edge cases are thoroughly tested, developers can build a more robust and reliable API. Laravel&#8217;s testing facilities are both powerful and developer-friendly, making it easier to maintain high code quality and application stability.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Best Practices &amp; Optimization<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Pagination &amp; Sorting<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In a RESTful API, implementing pagination and sorting ensures that data is efficiently delivered, enhancing the user experience. Laravel provides out-of-the-box support for both.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Pagination:<\/strong> With Laravel, you can paginate data simply by calling the <code>paginate<\/code> method on an Eloquent query. For example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-30\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">index<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n    <span class=\"hljs-keyword\">return<\/span> Book::paginate(<span class=\"hljs-number\">10<\/span>); <span class=\"hljs-comment\">\/\/ Returns 10 books per page<\/span>\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-30\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">You can customize the pagination views and even request a specific page from the client side.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Sorting:<\/strong> You can also allow clients to sort data by specific attributes. Here&#8217;s an example of how you might allow sorting by title:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-31\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">index<\/span><span class=\"hljs-params\">(Request $request)<\/span>\r\n<\/span>{\r\n    $query = Book::query();\r\n\r\n    <span class=\"hljs-keyword\">if<\/span> ($request-&gt;has(<span class=\"hljs-string\">'sort_by'<\/span>)) {\r\n        $query-&gt;orderBy($request-&gt;sort_by);\r\n    }\r\n\r\n    <span class=\"hljs-keyword\">return<\/span> $query-&gt;paginate();\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-31\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Rate Limiting<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Rate limiting protects your API from abuse and ensures fair usage. Laravel makes this simple. You can define rate limits in the <code>Kernel.php<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-32\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">protected<\/span> $middlewareGroups = &#91;\r\n    <span class=\"hljs-string\">'api'<\/span> =&gt; &#91;\r\n        <span class=\"hljs-string\">'throttle:60,1'<\/span>, <span class=\"hljs-comment\">\/\/ 60 requests per minute<\/span>\r\n        <span class=\"hljs-comment\">\/\/ other middleware...<\/span>\r\n    ],\r\n];<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-32\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Caching<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Caching can greatly optimize the API performance by storing the results of expensive or frequently-run queries. Laravel provides various ways to handle caching:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-33\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Support<\/span>\\<span class=\"hljs-title\">Facades<\/span>\\<span class=\"hljs-title\">Cache<\/span>;\r\n\r\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">index<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n    $books = Cache::remember(<span class=\"hljs-string\">'books'<\/span>, <span class=\"hljs-number\">60<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">()<\/span> <\/span>{\r\n        <span class=\"hljs-keyword\">return<\/span> Book::all(); <span class=\"hljs-comment\">\/\/ Cache this query for 60 seconds<\/span>\r\n    });\r\n\r\n    <span class=\"hljs-keyword\">return<\/span> $books;\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-33\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Error Handling<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Proper error handling is vital for providing meaningful feedback to clients. Laravel allows you to handle exceptions in the <code>Handler.php<\/code> file. Here&#8217;s an example of a custom exception handler:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-34\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">render<\/span><span class=\"hljs-params\">($request, Throwable $exception)<\/span>\r\n<\/span>{\r\n    <span class=\"hljs-keyword\">if<\/span> ($exception <span class=\"hljs-keyword\">instanceof<\/span> ModelNotFoundException) {\r\n        <span class=\"hljs-keyword\">return<\/span> response()-&gt;json(&#91;<span class=\"hljs-string\">'error'<\/span> =&gt; <span class=\"hljs-string\">'Resource not found'<\/span>], <span class=\"hljs-number\">404<\/span>);\r\n    }\r\n\r\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">parent<\/span>::render($request, $exception);\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-34\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">You can also use validation error handling to provide detailed error messages on invalid data submission:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-35\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">store<\/span><span class=\"hljs-params\">(Request $request)<\/span>\r\n<\/span>{\r\n    $validated = $request-&gt;validate(&#91;\r\n        <span class=\"hljs-string\">'title'<\/span> =&gt; <span class=\"hljs-string\">'required|max:255'<\/span>,\r\n        <span class=\"hljs-string\">'description'<\/span> =&gt; <span class=\"hljs-string\">'required'<\/span>,\r\n    ]);\r\n\r\n    <span class=\"hljs-keyword\">return<\/span> Book::create($validated);\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-35\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Documentation &amp; Deployment<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Documenting the API<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Creating comprehensive and user-friendly documentation is a critical step in the development of any API, ensuring that other developers and consumers understand how to interact with it. Tools like Swagger can automate this process, making it more efficient and maintainable.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In Laravel, you can utilize packages like L5-Swagger to integrate Swagger. After installing the package, you can annotate your controllers with the relevant information:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-36\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/**\r\n * <span class=\"hljs-doctag\">@OA<\/span>\\Get(\r\n *     path=\"\/api\/books\",\r\n *     <span class=\"hljs-doctag\">@OA<\/span>\\Response(response=\"200\", description=\"List of books\")\r\n * )\r\n *\/<\/span>\r\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">index<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n    <span class=\"hljs-keyword\">return<\/span> Book::all();\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-36\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">These annotations create an interactive documentation interface, allowing users to explore endpoints, understand expected request and response formats, and even test the endpoints directly through the user interface.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Properly documenting the API using tools like Swagger not only aids in the development process but also enhances collaboration and makes your API more accessible to a wider audience.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Deploying the API<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Once the API is developed, tested, and ready, the next phase is deployment. Laravel supports various platforms, and the choice may depend on factors like scalability, budget, and specific requirements.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>AWS (Amazon Web Services):<\/strong> Deploying on AWS can be a powerful option, providing various services tailored to your needs. AWS Elastic Beanstalk, for instance, is a fully managed service that can run and scale your Laravel application easily. You can use the AWS CLI or the Elastic Beanstalk Console to deploy and manage the application.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Heroku:<\/strong> Heroku offers a more straightforward approach and is a popular choice for deploying Laravel applications. You can create a <code>Procfile<\/code> to specify the commands that should be executed to start your application and then push the code to Heroku using Git. Heroku handles the rest, from provisioning the server to managing the database.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>DigitalOcean, Linode, or other VPS Providers:<\/strong> For more control over the environment, you may consider deploying on a Virtual Private Server (VPS) like DigitalOcean or Linode. Laravel has a tool called Forge, specifically designed to automate the deployment of Laravel applications on these platforms, making the process simpler.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">No matter the platform, understanding the specific requirements and constraints of the API, and choosing the right tools and services accordingly, is key to successful deployment.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In conclusion, documenting and deploying are the final but vital steps in building a RESTful API with Laravel. Using tools like Swagger, the API documentation can be automated and kept synchronized with the codebase. Deployment options are varied, with platforms like AWS, Heroku, and various VPS providers offering different advantages. The combination of effective documentation and thoughtful deployment ensures that the API is accessible, maintainable, and ready to serve its intended audience.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Overview of RESTful APIs Representational State Transfer (REST) is an architectural style that defines a set of constraints and properties based on HTTP. RESTful APIs are designed to handle the creation, reading, updating, and deletion (CRUD) of resources, which are represented in a textual format like JSON. Key Principles: The benefits of using RESTful [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[20,4],"tags":[],"class_list":["post-914","post","type-post","status-publish","format-standard","category-php","category-programming-languages","entry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Building a RESTful API with Laravel<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.w3computing.com\/articles\/building-restful-api-laravel\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Building a RESTful API with Laravel\" \/>\n<meta property=\"og:description\" content=\"Introduction Overview of RESTful APIs Representational State Transfer (REST) is an architectural style that defines a set of constraints and properties based on HTTP. RESTful APIs are designed to handle the creation, reading, updating, and deletion (CRUD) of resources, which are represented in a textual format like JSON. Key Principles: The benefits of using RESTful [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.w3computing.com\/articles\/building-restful-api-laravel\/\" \/>\n<meta property=\"article:published_time\" content=\"2023-08-15T22:35:15+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-08-23T16:20:20+00:00\" \/>\n<meta name=\"author\" content=\"w3compadmin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"w3compadmin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"TechArticle\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-restful-api-laravel\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-restful-api-laravel\\\/\"},\"author\":{\"name\":\"w3compadmin\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"headline\":\"Building a RESTful API with Laravel\",\"datePublished\":\"2023-08-15T22:35:15+00:00\",\"dateModified\":\"2023-08-23T16:20:20+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-restful-api-laravel\\\/\"},\"wordCount\":2226,\"commentCount\":0,\"articleSection\":[\"PHP\",\"Programming Languages\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-restful-api-laravel\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-restful-api-laravel\\\/\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-restful-api-laravel\\\/\",\"name\":\"Building a RESTful API with Laravel\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\"},\"datePublished\":\"2023-08-15T22:35:15+00:00\",\"dateModified\":\"2023-08-23T16:20:20+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-restful-api-laravel\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-restful-api-laravel\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-restful-api-laravel\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Articles Home\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Programming Languages\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/programming-languages\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Building a RESTful API with Laravel\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\",\"name\":\"Developer Articles Hub\",\"description\":\"\",\"alternateName\":\"Developer Articles\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\",\"name\":\"w3compadmin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"contentUrl\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"caption\":\"w3compadmin\"},\"sameAs\":[\"http:\\\/\\\/w3computing.com\\\/articles\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Building a RESTful API with Laravel","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.w3computing.com\/articles\/building-restful-api-laravel\/","og_locale":"en_US","og_type":"article","og_title":"Building a RESTful API with Laravel","og_description":"Introduction Overview of RESTful APIs Representational State Transfer (REST) is an architectural style that defines a set of constraints and properties based on HTTP. RESTful APIs are designed to handle the creation, reading, updating, and deletion (CRUD) of resources, which are represented in a textual format like JSON. Key Principles: The benefits of using RESTful [&hellip;]","og_url":"https:\/\/www.w3computing.com\/articles\/building-restful-api-laravel\/","article_published_time":"2023-08-15T22:35:15+00:00","article_modified_time":"2023-08-23T16:20:20+00:00","author":"w3compadmin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"w3compadmin","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"TechArticle","@id":"https:\/\/www.w3computing.com\/articles\/building-restful-api-laravel\/#article","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/building-restful-api-laravel\/"},"author":{"name":"w3compadmin","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"headline":"Building a RESTful API with Laravel","datePublished":"2023-08-15T22:35:15+00:00","dateModified":"2023-08-23T16:20:20+00:00","mainEntityOfPage":{"@id":"https:\/\/www.w3computing.com\/articles\/building-restful-api-laravel\/"},"wordCount":2226,"commentCount":0,"articleSection":["PHP","Programming Languages"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.w3computing.com\/articles\/building-restful-api-laravel\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.w3computing.com\/articles\/building-restful-api-laravel\/","url":"https:\/\/www.w3computing.com\/articles\/building-restful-api-laravel\/","name":"Building a RESTful API with Laravel","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/#website"},"datePublished":"2023-08-15T22:35:15+00:00","dateModified":"2023-08-23T16:20:20+00:00","author":{"@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"breadcrumb":{"@id":"https:\/\/www.w3computing.com\/articles\/building-restful-api-laravel\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.w3computing.com\/articles\/building-restful-api-laravel\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.w3computing.com\/articles\/building-restful-api-laravel\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Articles Home","item":"https:\/\/www.w3computing.com\/articles\/"},{"@type":"ListItem","position":2,"name":"Programming Languages","item":"https:\/\/www.w3computing.com\/articles\/programming-languages\/"},{"@type":"ListItem","position":3,"name":"Building a RESTful API with Laravel"}]},{"@type":"WebSite","@id":"https:\/\/www.w3computing.com\/articles\/#website","url":"https:\/\/www.w3computing.com\/articles\/","name":"Developer Articles Hub","description":"","alternateName":"Developer Articles","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.w3computing.com\/articles\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561","name":"w3compadmin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","url":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","contentUrl":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","caption":"w3compadmin"},"sameAs":["http:\/\/w3computing.com\/articles"]}]}},"featured_image_src":null,"featured_image_src_square":null,"author_info":{"display_name":"w3compadmin","author_link":"https:\/\/www.w3computing.com\/articles\/author\/w3compadmin\/"},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/914","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/comments?post=914"}],"version-history":[{"count":11,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/914\/revisions"}],"predecessor-version":[{"id":925,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/914\/revisions\/925"}],"wp:attachment":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/media?parent=914"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/categories?post=914"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/tags?post=914"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}