erag / laravel-case-mapper-request
Seamlessly integrate attribute-based case mapping into Laravel FormRequests — transform keys and remap validation errors effortlessly.
Fund package maintenance!
eramitgupta
Requires
- php: ^8.1
- illuminate/support: ^10.0|^11.0|^12.0
- laravel/pint: ^1.13
README
A Laravel package that transforms request input keys using PHP 8+ attributes. Supports formats like camelCase, snake_case, StudlyCase, UPPERCASE, enabling flexible data handling from varied sources. Ideal for backend services needing consistent input structures, regardless of client naming conventions.
📦 Designed for Laravel 10, 11, and 12 — No core modification required.
✨ Features
- 🧠 Automatically map incoming request keys to match your validation expectations
- 🧩 Attribute-based syntax using
#[MapName(...)]
- 🔄 Supports multiple naming conventions
- 🧩 Integrates seamlessly with Laravel
FormRequest
- 📚 Extendable with custom mappers
- ✅ Zero configuration, zero core hacks
- 🎨 Works with any frontend (React, Vue, etc.)
💡 Recommended: Vue or React for best developer experience
🔧 Supported Case Mappers
Mapper Class | Frontend Input | Validated As output |
---|---|---|
SnakeCaseMapper |
firstName |
first_name |
CamelCaseMapper |
first_name |
firstName |
StudlyCaseMapper |
FirstName |
first_name |
UpperCaseMapper |
FIRSTNAME |
firstname |
📦 Installation
composer require erag/laravel-case-mapper-request
No config file or publishing required.
Create a Form Request with Case Mapping
🧩 1. Create a Form Request class
php artisan make:request ContactRequest
🧩 2. Add the attribute and trait
use LaravelCaseMapperRequest\Attributes\MapName; use LaravelCaseMapperRequest\Traits\HasKeyTransformers; use LaravelCaseMapperRequest\Mappers\SnakeCaseMapper; #[MapName(SnakeCaseMapper::class)] // or CamelCaseMapper, UpperCaseMapper, StudlyCaseMapper etc. class ContactRequest extends FormRequest { use HasKeyTransformers; public function authorize(): bool { return true; } public function rules(): array { return [ 'first_name' => 'required|string', 'last_name' => 'required|string', 'email_address' => 'required|email', ]; } }
🧩 3. Use it in a Controller
use App\Http\Requests\ContactRequest; class ContactController extends Controller { public function store(ContactRequest $request) { $validated = $request->validated(); // Example: // Contact::create($validated); return response()->json([ 'message' => 'Submitted successfully!', 'data' => $validated ]); } }
Step 3: Frontend Input Example (Vue + Inertia)
<template> <form @submit.prevent="submit"> <input v-model="form.firstName" placeholder="First Name" /> <input v-model="form.lastName" placeholder="Last Name" /> <input v-model="form.emailAddress" placeholder="Email" /> <button type="submit">Submit</button> </form> </template> <script setup> import { useForm } from '@inertiajs/vue3' const form = useForm({ firstName: '', lastName: '', emailAddress: '' }) function submit() { form.post('/form/snake') } </script>
Step 4: Backend Automatically Maps It
Incoming :
{ "firstName": "Amit", "lastName": "Gupta", "emailAddress": "amit@example.com" }
Mapped for Validation output:
[ 'first_name' => 'Amit', 'last_name' => 'Gupta', 'email_address' => 'amit@example.com' ]
🧠 Defining Your Own Case Mapper
Need to support a custom casing style or transformation logic?
You can easily create your own mapper by implementing the CaseMapperContract
Just implement the contract:
use LaravelCaseMapperRequest\Contracts\CaseMapperContract; class KebabCaseMapper implements CaseMapperContract { public static function map(array $data): array { return collect($data) ->mapWithKeys(fn($value, $key) => [Str::kebab($key) => $value]) ->toArray(); } }
Then apply to any FormRequest:
#[MapName(KebabCaseMapper::class)]
📄 License
MIT © Amit Gupta
🔗 Connect
Made with ❤️ by Amit Gupta
⭐ Found this useful? Star it on GitHub!