CoderFunda
  • Home
  • About us
    • Contact Us
    • Disclaimer
    • Privacy Policy
    • About us
  • Home
  • Php
  • HTML
  • CSS
  • JavaScript
    • JavaScript
    • Jquery
    • JqueryUI
    • Stock
  • SQL
  • Vue.Js
  • Python
  • Wordpress
  • C++
    • C++
    • C
  • Laravel
    • Laravel
      • Overview
      • Namespaces
      • Middleware
      • Routing
      • Configuration
      • Application Structure
      • Installation
    • Overview
  • DBMS
    • DBMS
      • PL/SQL
      • SQLite
      • MongoDB
      • Cassandra
      • MySQL
      • Oracle
      • CouchDB
      • Neo4j
      • DB2
      • Quiz
    • Overview
  • Entertainment
    • TV Series Update
    • Movie Review
    • Movie Review
  • More
    • Vue. Js
    • Php Question
    • Php Interview Question
    • Laravel Interview Question
    • SQL Interview Question
    • IAS Interview Question
    • PCS Interview Question
    • Technology
    • Other

25 August, 2022

SON API Resources in Laravel

 Programing Coderfunda     August 25, 2022     Laravel, Laravel Tutorials     No comments   

 

SON API Resources in Laravel

Building APIs in Laravel is a passion of mine, and I have spent a lot of time searching for the perfect way to return consistent JSON:API friendly resources so that I can find and use a standard.

In the past, I have used a cobbled-together solution that would just about manage to achieve what I needed, but it was quite a bit of work. The negatives outweighed the benefits of this approach, as the development time spent achieving it just felt like it wasn't worth it.

Luckily for you and me, Tim MacDonald built a fantastic package for this use case. It allows us to build and return JSON:API compliant resources that are easy to use. Let's walk through how this works.

Typically when building an API resource, we would extend Laravels JsonResource or CollectionResource depending on what we wanted to achieve. Our typical Resource might look like the following:

1class PostResource extends JsonResource
2{
3 public function toArray($request): array
4 {
5 return [
6 'id' => $this->id,
7 'type' => 'post',
8 'attributes' => [
9 'title' => $this->title,
10 'slug' => $this->slug,
11 'content' => $this->content,
12 ]
13 ];
14 }
15}

We are adding a simple implementation to "fake" a JSON:API resource at a basic level. But as you can see, this is a little - yuck. Let's install the package by Tim:

1composer require timacdonald/json-api

Now we can refactor the above resource to follow JSON:API standards. Let me walk you through the changes.

Firstly, we need to change what class we are extending from JsonResource to JsonApiResource:

1class PostResource extends JsonApiResource

The next thing we need to make sure that we change is to remove the toArray method, as this package will handle this under the hood for you - instead, we use different methods that are useful for JSON:API standards. For example, to add attributes to your resource, you can use the following method:

1protected function toAttributes(Request $request): array
2{
3 return [
4 'title' => $this->title,
5 'slug' => $this->slug,
6 'content' => $this->content,
7 ];
8}

Now let's look at relationships. Previously we would do something similar to:

1 return [
2 'id' => $this->id,
3 'type' => 'post',
4 'attributes' => [
5 'title' => $this->title,
6 'slug' => $this->slug,
7 'content' => $this->content,
8 ],
9 'relationships' => [
10 'category' => new CategoryResource(
11 resource: $this->whenLoaded('category'),
12 ),
13 ]
14];

This isn't a bad way to do it by any means; however, let us have a look at how we would add these on the JSON:API package:

1protected function toRelationships(Request $request): array
2{
3 return [
4 'category' => fn () => new CategoryResource(
5 resource: $this->category,
6 ),
7 ];
8}

So this time, we are passing through a closure to be evaluated to return the relationship. This is a very powerful way to do this, as it opens us up to add very custom behavior to relationship loading - meaning that we can load different conditional relationships or run authorization on the resource. Another point to note is that the closure is only evaluated when the client has included the relationship - making it a little cleaner.

Taking this another step further, adding links to your API resources is something that I feel is an important step. Adding these links makes your API navigatable, allowing clients to follow links as required programmatically. Previously I would add another array entry to add these and use the route helper to echo these out. The JSON:API package has an alternative approach, which is particularly fluent:

1protected function toLinks(Request $request): array
2{
3 return [
4 Link::self(route('api:v1:posts:show', $this->resource)),
5 ];
6}

As you can see - it is fluent, simple, and will generate the correct link for you. Of course, you are welcome to add what you need here, but it will add the links in a JSON:API standardized way - so you don't have to.

Finally, meta-data, in JSON:API, you can add additional information within the meta-object so you can add documentation links or anything you might need to pass back with an API resource (depending on your API design). There aren't a million use cases for this, but the package does support it. So let's have a look at this to understand it.

1protected function toMeta(Request $request): array
2{
3 return [
4 'depreciated' => false,
5 'docs' => 'https://docs.domain/com/resources/posts',
6 ];
7}

As you can see above, we can add depreciation warnings so that clients can be notified of resources they need to consider changing - and a link to the docs explaining the replacement approach.

How do you build your API resources? Are you following any specific standards? Let us know on Twitter!

  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg
Email ThisBlogThis!Share to XShare to Facebook

Related Posts:

  • Multidimensional array searching to return key if value found<?Multidimensional array searching to return key if value foundI need to pass in a… Read More
  • Latest 20 Laravel Eloquent Tips and Tricks  Eloquent ORM seems like a simple mechanism, but under the hood, there’s a lot of semi-hidden functions and less-known ways to achieve more with … Read More
  • How can we Create Multiple Where Clause Query Using Laravel Eloquent? I'm using the Laravel Eloquent query builder and I have a query where I want a WHERE clause on multiple conditions. It works, but it's… Read More
  • Laravel Query Builder & Eloquent ORM An application always needs to interact with a database and Laravel makes this task hassle free. Few tools that make Laravel an awesome framewor… Read More
  • Laravel Interview Questions And Answers 2020 1) What is the Laravel?A) Laravel is an open-source PHP web framework, created for the development of web applications following the model–view–… Read More
Newer Post Older Post Home

0 comments:

Post a Comment

Thanks

Meta

Popular Posts

  • Spring boot app (error: method getFirst()) failed to run at local machine, but can run on server
    The Spring boot app can run on the online server. Now, we want to replicate the same app at the local machine but the Spring boot jar file f...
  • Log activity in a Laravel app with Spatie/Laravel-Activitylog
      Requirements This package needs PHP 8.1+ and Laravel 9.0 or higher. The latest version of this package needs PHP 8.2+ and Laravel 8 or hig...
  • Laravel auth login with phone or email
          <?php     Laravel auth login with phone or email     <? php     namespace App \ Http \ Controllers \ Auth ;         use ...
  • Failed to install 'cordova-plugin-firebase': CordovaError: Uh oh
    I had follow these steps to install an configure firebase to my cordova project for cloud messaging. https://medium.com/@felipepucinelli/how...
  • Vue3 :style backgroundImage not working with require
    I'm trying to migrate a Vue 2 project to Vue 3. In Vue 2 I used v-bind style as follow: In Vue 3 this doesn't work... I tried a...

Categories

  • Ajax (26)
  • Bootstrap (30)
  • DBMS (42)
  • HTML (12)
  • HTML5 (45)
  • JavaScript (10)
  • Jquery (34)
  • Jquery UI (2)
  • JqueryUI (32)
  • Laravel (1017)
  • Laravel Tutorials (23)
  • Laravel-Question (6)
  • Magento (9)
  • Magento 2 (95)
  • MariaDB (1)
  • MySql Tutorial (2)
  • PHP-Interview-Questions (3)
  • Php Question (13)
  • Python (36)
  • RDBMS (13)
  • SQL Tutorial (79)
  • Vue.js Tutorial (68)
  • Wordpress (150)
  • Wordpress Theme (3)
  • codeigniter (108)
  • oops (4)
  • php (853)

Social Media Links

  • Follow on Twitter
  • Like on Facebook
  • Subscribe on Youtube
  • Follow on Instagram

Pages

  • Home
  • Contact Us
  • Privacy Policy
  • About us

Blog Archive

  • September (100)
  • August (50)
  • July (56)
  • June (46)
  • May (59)
  • April (50)
  • March (60)
  • February (42)
  • January (53)
  • December (58)
  • November (61)
  • October (39)
  • September (36)
  • August (36)
  • July (34)
  • June (34)
  • May (36)
  • April (29)
  • March (82)
  • February (1)
  • January (8)
  • December (14)
  • November (41)
  • October (13)
  • September (5)
  • August (48)
  • July (9)
  • June (6)
  • May (119)
  • April (259)
  • March (122)
  • February (368)
  • January (33)
  • October (2)
  • July (11)
  • June (29)
  • May (25)
  • April (168)
  • March (93)
  • February (60)
  • January (28)
  • December (195)
  • November (24)
  • October (40)
  • September (55)
  • August (6)
  • July (48)
  • May (2)
  • January (2)
  • July (6)
  • June (6)
  • February (17)
  • January (69)
  • December (122)
  • November (56)
  • October (92)
  • September (76)
  • August (6)

  • Failed to install 'cordova-plugin-firebase': CordovaError: Uh oh - 9/21/2024
  • pyspark XPath Query Returns Lists Omitting Missing Values Instead of Including None - 9/20/2024
  • SQL REPL from within Python/Sqlalchemy/Psychopg2 - 9/20/2024
  • MySql Explain with Tobias Petry - 9/20/2024
  • How to combine information from different devices into one common abstract virtual disk? [closed] - 9/20/2024

Laravel News

  • Validate Controller Requests with the Laravel Data Package - 5/19/2025
  • Deployer - 5/18/2025
  • Transform JSON into Typed Collections with Laravel's AsCollection::of() - 5/18/2025
  • Auto-translate Application Strings with Laratext - 5/16/2025
  • Simplify Factory Associations with Laravel's UseFactory Attribute - 5/13/2025

Copyright © 2025 CoderFunda | Powered by Blogger
Design by Coderfunda | Blogger Theme by Coderfunda | Distributed By Coderfunda