title: Laravel / nested validation
body: <p>I am building a component-driven API for a basic page-builder system and have hit a stumbling block when it comes to validation.</p>
  
  <p>First, I want to explain the use-case.</p>
  
  <p>if we have a component (for example in Vue) in <code>/components/ProfileCard.vue</code></p>
  
  <pre class="lang-html prettyprint-override"><code>&lt;script&gt;
  export default {
      props: {
          name: String,
          age: Number,
          avatar: String
      }
  }
  &lt;/script&gt;
  
  </code></pre>
  
  <p>I am creating a component in the backend  <code>components.php</code> config:</p>
  
  <pre class="lang-php prettyprint-override"><code>
  &lt;?php
  
  return [
      'profile' =&gt; [
          'component' =&gt; 'ProfileCard',
          'rules' =&gt; [
              'name' =&gt; [
                  'required',
              ],
              'age' =&gt; [
                  'required',
                  'number',
              ],
              'avatar' =&gt; [
                  'required',
              ]
          ],
      ],
  ];
  
  </code></pre>
  
  <p>Which checks and validates every time a profile card component is submitted.</p>
  
  <p>Creating a custom validation rule for Component, I am able to say "the ProfileCard component is not valid" but I am not able to merge / nest the validation rules:</p>
  
  <p><code>Component.php</code></p>
  
  <pre class="lang-php prettyprint-override"><code>&lt;?php
  
  namespace App\Rules;
  
  use Illuminate\Contracts\Validation\Rule;
  use Illuminate\Support\Facades\Validator;
  
  class Component implements Rule 
  {
      protected $validator = null;
  
      public function passes($attribute, $value)
      {
          $components = config('components');
          $component = $value['component'];
  
          if (isset($components[$component])) {
              return false;
          }
  
          $c = $components[$component];
          $this-&gt;validator = Validator::make($value['data'], $c['rules'], $c['messages'] ?? '');
          return $this-&gt;validator-&gt;passes();
      }
  
      public function message() 
      {
          if (is_null($this-&gt;validator)) {
              return 'The component does not exist';
          }
          return $this-&gt;validator-&gt;errors();
      }
  }
  
  </code></pre>
  
  <p>Has anybody got any experience doing anything like this or can anybody point me in the right direction towards a solution?</p>
  
  <p>I am ideally looking for a solution which is applicable while using Laravel's FormRequest validation, like so:</p>
  
  <pre class="lang-php prettyprint-override"><code>namespace App\Http\Requests;
  
  use Illuminate\Foundation\Http\FormRequest;
  use Illuminate\Validation\Rules\Unique;
  use App\Rules\Component;
  
  class CreateUserRequest extends FormRequest
  {
      public function authorize()
      {
          return true;
      }
  
      public function rules()
      {
          return [
              'email' =&gt; [
                  'required',
                  'email',
                  new Unique('users', 'email'),
              ],
              'profile' =&gt; [
                  'required',
                  new Component(),
              ]
          ];
      }
  }
  
  </code></pre>
  
  <p>The data would come in like so:</p>
  
  <pre><code>{
      "email": "test@example.com",
      "profile": {
          "component": "ProfileCard",
          "data": {
             "name": "Test",
             "age": 49,
             "avatar": "https://example.com/avatar.png"
          }
      }
  }
  </code></pre>
  
  <p>I have updated the question with the progress I have made myself, you can return a <code>MessageBag</code> in the <code>messages</code> method on the rule, however, this creates a slight problem, the response comes back as follows:</p>
  
  <pre><code>
      "message": "The given data was invalid.",
      "errors": {
          "profile": [
              {
                  "name": [
                      "The name field is required."
                  ],
                  "age": [
                      "The age field is required."
                  ],
                  "avatar": [
                      "The avatar field is required."
                  ],
              },
              ":message"
          ]
      }
  
  </code></pre>
  
  <p>Clearly this is an improvement but it's still not as usable, we don't have a ':message' and the validation errors are nested in an object in the "profile" array.</p>