Store JSON In Database – Laravel 12 – A Complete Guide

JSON (JavaScript Object Notation) has become the universal standard for data exchange in modern web applications. Its lightweight, human-readable format makes it ideal for APIs, configuration files, and handling unstructured data in databases.

In Laravel applications, we often encounter scenarios where:

  • We need to store large datasets without creating numerous database columns
  • The data structure is dynamic or unpredictable
  • We want to maintain complex nested relationships in a single field

This tutorial will walk you through storing and retrieving JSON data in a Laravel 12 application with proper type casting and database optimization.

Setting Up the Project

Step 1: Install Laravel 12

Begin by creating a new Laravel project:

composer create-project laravel/laravel json-storage-app
cd json-storage-app

Step 2: Create Migration with JSON Column

Generate a migration for our sample “items” table:

php artisan make:migration create_items_table

Define the table structure with a JSON column:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('items', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->json('data')->nullable(); // JSON column for our unstructured data
            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('items');
    }
};

Run the migration:

php artisan migrate

Creating the Model with JSON Casting

Step 3: Generate and Configure the Model

Create the Item model:

php artisan make:model Item

Implement proper JSON casting:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Casts\Attribute;

class Item extends Model
{
    use HasFactory;

    protected $fillable = [
        'title', 
        'data' // Allow mass assignment for these fields
    ];

    protected function data(): Attribute
    {
        return Attribute::make(
            get: fn ($value) => json_decode($value, true), // Convert JSON to array when retrieving
            set: fn ($value) => json_encode($value), // Convert array to JSON when storing
        )->shouldCache();
    }
}

Implementing the Controller Logic

Step 4: Set Up the Route

Define a test route in routes/web.php:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ItemController;

Route::get('items', [ItemController::class, 'storeAndRetrieve']);

Step 5: Create the Controller

Generate and configure the controller:

php artisan make:controller ItemController

Add the demonstration logic:

<?php

namespace App\Http\Controllers;

use App\Models\Item;

class ItemController extends Controller
{
    public function storeAndRetrieve()
    {
        // Sample data structure
        $itemData = [
            'title' => 'Sample Item',
            'data' => [
                'metadata' => [
                    'author' => 'John Doe',
                    'version' => 1.2
                ],
                'tags' => ['laravel', 'json', 'storage'],
                'settings' => [
                    'notifications' => true,
                    'retry_count' => 3
                ]
            ]
        ];

        // Store the item
        $item = Item::create($itemData);

        // Retrieve and display the JSON data
        return response()->json([
            'stored_data' => $item->data,
            'specific_value' => $item->data['metadata']['author']
        ]);
    }
}

Testing the Implementation

Run the development server:

php artisan serve

Visit the test endpoint:

http://localhost:8000/items

You should see output similar to:

{
    "stored_data": {
        "metadata": {
            "author": "John Doe",
            "version": 1.2
        },
        "tags": ["laravel", "json", "storage"],
        "settings": {
            "notifications": true,
            "retry_count": 3
        }
    },
    "specific_value": "John Doe"
}

Best Practices for JSON Storage in Laravel

  1. Schema Design: Use JSON columns for truly dynamic data, not as a replacement for proper relational design
  2. Indexing: Consider adding generated columns for fields you’ll search frequently
  3. Validation: Always validate JSON data before storage
  4. Querying: Use Laravel’s JSON query operators for efficient searching
  5. Documentation: Clearly document your JSON structure for future maintainability

This implementation provides a solid foundation for working with JSON data in Laravel 12, combining the flexibility of NoSQL concepts with the power of Eloquent ORM.

Previous Article

Dynamic Dependent AJAX Dropdowns - Laravel 12

Write a Comment

Leave a Comment

Your email address will not be published. Required fields are marked *


Subscribe to our Newsletter

Subscribe to our email newsletter to get the latest posts delivered right to your email.
Pure inspiration, zero spam ✨