Skip to content

Commit

Permalink
Support Responsable objects.
Browse files Browse the repository at this point in the history
This is the foundation for allowing objects to be converted into full
HTTP responses, allowing more fluent API packages to be built in the
future.
  • Loading branch information
taylorotwell committed Jun 1, 2017
1 parent ba6cc92 commit c0c89fd
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 1 deletion.
13 changes: 13 additions & 0 deletions src/Illuminate/Contracts/Support/Responsable.php
@@ -0,0 +1,13 @@
<?php

namespace Illuminate\Contracts\Support;

interface Responsable
{
/**
* Create an HTTP response that represents the object.
*
* @return \Illuminate\Http\Response
*/
public function toResponse();
}
3 changes: 2 additions & 1 deletion src/Illuminate/Routing/Pipeline.php
Expand Up @@ -71,7 +71,8 @@ protected function carry()
*/ */
protected function handleException($passable, Exception $e) protected function handleException($passable, Exception $e)
{ {
if (! $this->container->bound(ExceptionHandler::class) || ! $passable instanceof Request) { if (! $this->container->bound(ExceptionHandler::class) ||
! $passable instanceof Request) {
throw $e; throw $e;
} }


Expand Down
3 changes: 3 additions & 0 deletions src/Illuminate/Routing/Router.php
Expand Up @@ -15,6 +15,7 @@
use Illuminate\Contracts\Support\Jsonable; use Illuminate\Contracts\Support\Jsonable;
use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Contracts\Support\Arrayable; use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Contracts\Support\Responsable;
use Illuminate\Contracts\Routing\BindingRegistrar; use Illuminate\Contracts\Routing\BindingRegistrar;
use Psr\Http\Message\ResponseInterface as PsrResponseInterface; use Psr\Http\Message\ResponseInterface as PsrResponseInterface;
use Illuminate\Contracts\Routing\Registrar as RegistrarContract; use Illuminate\Contracts\Routing\Registrar as RegistrarContract;
Expand Down Expand Up @@ -620,6 +621,8 @@ public static function prepareResponse($request, $response)
{ {
if ($response instanceof PsrResponseInterface) { if ($response instanceof PsrResponseInterface) {
$response = (new HttpFoundationFactory)->createResponse($response); $response = (new HttpFoundationFactory)->createResponse($response);
} elseif ($response instanceof Responsable) {
$response = $response->toResponse();
} elseif (! $response instanceof SymfonyResponse && } elseif (! $response instanceof SymfonyResponse &&
($response instanceof Arrayable || ($response instanceof Arrayable ||
$response instanceof Jsonable || $response instanceof Jsonable ||
Expand Down
33 changes: 33 additions & 0 deletions tests/Integration/Routing/ResponsableTest.php
@@ -0,0 +1,33 @@
<?php

use Orchestra\Testbench\TestCase;
use Illuminate\Support\Facades\Route;
use Illuminate\Contracts\Support\Responsable;

/**
* @group integration
*/
class ResponsableTest extends TestCase
{
public function test_responsable_objects_are_rendered()
{
Route::get('/responsable', function () {
return new TestResponsableResponse;
});

$response = $this->get('/responsable');

$this->assertEquals(201, $response->status());
$this->assertEquals('Taylor', $response->headers->get('X-Test-Header'));
$this->assertEquals('hello world', $response->getContent());
}
}


class TestResponsableResponse implements Responsable
{
public function toResponse()
{
return response('hello world', 201, ['X-Test-Header' => 'Taylor']);
}
}

0 comments on commit c0c89fd

Please sign in to comment.