Last active
September 22, 2019 21:50
-
-
Save matthewerskine/09af2ad5031f9c318e03b7f41bdd59de to your computer and use it in GitHub Desktop.
Laravel 5.5 Request Director
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| use App\Http\ResourceDirector; | |
| if (! function_exists('store')) { | |
| /** | |
| * Stores a new resource using the ResourceDirector. | |
| * | |
| * @param string $resource | |
| * @param string|closure $using | |
| * @return \Illuminate\Http\Resources\Json\Resource | |
| */ | |
| function store($resource, $using) | |
| { | |
| return app(ResourceDirector::class)->store($resource, $using); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace App\Http; | |
| use Illuminate\Http\JsonResponse; | |
| use Illuminate\Validation\ValidationException; | |
| use App\Contracts\Http\Resources\ValidatorResourceContract; | |
| class ResourceDirector | |
| { | |
| /** | |
| * Validates, stores and responds with a new resource. | |
| * | |
| * @param string $resourceClass | |
| * @param string|closure $using | |
| * @param \Illuminate\Http\Request|null $request | |
| * @return \Illuminate\Http\Resources\Json\Resource | |
| */ | |
| public function store($resourceClass, $using, $request = null) | |
| { | |
| $request = $request ?? request(); | |
| return tap(new $resourceClass(null), function($resource) use($using, $request) { | |
| $this->validateIfApplicable($resource, $request); | |
| $resource->resource = is_callable($using) | |
| ? $using($request) | |
| : (new $using)->create($request->input()); | |
| }); | |
| } | |
| /** | |
| * Validates a given request if the resource is described to do so. | |
| * | |
| * @param \Illuminate\Http\Resources\Json\Resource $resource | |
| * @param \Illuminate\Http\Request $request | |
| * @return void | |
| * | |
| * @throws \Illuminate\Validation\ValidationException | |
| */ | |
| protected function validateIfApplicable($resource, $request) | |
| { | |
| if (!$resource instanceof ValidatorResourceContract) { | |
| return false; | |
| } | |
| try { | |
| $resource->validate($request, $validator = app('validator')); | |
| } catch (ValidationException $exception) { | |
| throw new ValidationException($validator, new JsonResponse( | |
| $exception->errors(), 422 | |
| )); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| use App\Http\ResourceDirector; | |
| use Illuminate\Database\Eloquent\Model; | |
| use Illuminate\Http\Resources\Json\Resource; | |
| use Illuminate\Validation\ValidationException; | |
| use App\Contracts\Http\Resources\ValidatorResourceContract; | |
| class ResourceDirectorTest extends TestCase | |
| { | |
| public function setup() | |
| { | |
| parent::setup(); | |
| $this->director = new ResourceDirector; | |
| } | |
| public function test_it_validates_the_request_as_directed_by_the_resource() | |
| { | |
| $this->expectException(ValidationException::class); | |
| $resource = $this->director->store(TestResource::class, TestModel::class); | |
| } | |
| public function test_it_responds_with_a_filled_resource() | |
| { | |
| $resource = $this->director->store(TestResource::class, TestModel::class, tap(request(), function($request) { | |
| $request->merge(['foo' => '123']); | |
| })); | |
| $this->assertEquals('bar', $resource->foo); | |
| $this->assertEquals('bar', $resource->toArray(null)['foo']); | |
| } | |
| public function test_a_custom_callback_can_instantiate_the_model() | |
| { | |
| $request = request(); | |
| $request->merge(['foo' => 123]); | |
| $resource = $this->director->store(TestResource::class, function($request) { | |
| return (object) ['foo' => '999']; | |
| }, $request); | |
| $this->assertEquals('999', $resource->foo); | |
| } | |
| public function test_it_supports_resources_that_do_not_require_validation() | |
| { | |
| $resource = $this->director->store(TestResourceNoValidation::class, function($request) { | |
| return ['ok']; | |
| }); | |
| $this->assertEquals(['ok'], $resource->resource); | |
| } | |
| } | |
| class TestModel | |
| { | |
| public function create() | |
| { | |
| return (object) ['foo' => 'bar']; | |
| } | |
| } | |
| class TestResourceNoValidation extends Resource | |
| { | |
| // | |
| } | |
| class TestResource extends Resource implements ValidatorResourceContract | |
| { | |
| public function validate($request, $validator) | |
| { | |
| return $validator->validate($request->input(), [ | |
| 'foo' => 'required', | |
| ]); | |
| } | |
| public function toArray($request) | |
| { | |
| return ['foo' => $this->foo]; | |
| } | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace App\Http\Resources; | |
| use Illuminate\Http\Resources\Json\Resource; | |
| use App\Contracts\Http\Resources\ValidatorResourceContract; | |
| class UserResource extends Resource implements ValidatorResourceContract | |
| { | |
| public function validate($request, $validator) | |
| { | |
| $validator->validate($request->input(), [ | |
| 'first_name' => 'required', | |
| 'last_name' => 'required', | |
| ]); | |
| } | |
| public function toArray($request) | |
| { | |
| return [ | |
| 'last_name' => $this->last_name, | |
| 'first_name' => $this->first_name, | |
| ]; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace App\Contracts\Http\Resources; | |
| interface ValidatorResourceContract | |
| { | |
| /** | |
| * Validates the request. | |
| * | |
| * @param \Illuminate\Http\Request $request | |
| * @param \Illuminate\Validation\Validator $validator | |
| * @return void | |
| */ | |
| public function validate($request, $validator); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment