Skip to content

Commit c0c89fd

Browse files
committed
Support Responsable objects.
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.
1 parent ba6cc92 commit c0c89fd

4 files changed

Lines changed: 51 additions & 1 deletion

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Illuminate\Contracts\Support;
4+
5+
interface Responsable
6+
{
7+
/**
8+
* Create an HTTP response that represents the object.
9+
*
10+
* @return \Illuminate\Http\Response
11+
*/
12+
public function toResponse();
13+
}

‎src/Illuminate/Routing/Pipeline.php‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ protected function carry()
7171
*/
7272
protected function handleException($passable, Exception $e)
7373
{
74-
if (! $this->container->bound(ExceptionHandler::class) || ! $passable instanceof Request) {
74+
if (! $this->container->bound(ExceptionHandler::class) ||
75+
! $passable instanceof Request) {
7576
throw $e;
7677
}
7778

‎src/Illuminate/Routing/Router.php‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Illuminate\Contracts\Support\Jsonable;
1616
use Illuminate\Contracts\Events\Dispatcher;
1717
use Illuminate\Contracts\Support\Arrayable;
18+
use Illuminate\Contracts\Support\Responsable;
1819
use Illuminate\Contracts\Routing\BindingRegistrar;
1920
use Psr\Http\Message\ResponseInterface as PsrResponseInterface;
2021
use Illuminate\Contracts\Routing\Registrar as RegistrarContract;
@@ -620,6 +621,8 @@ public static function prepareResponse($request, $response)
620621
{
621622
if ($response instanceof PsrResponseInterface) {
622623
$response = (new HttpFoundationFactory)->createResponse($response);
624+
} elseif ($response instanceof Responsable) {
625+
$response = $response->toResponse();
623626
} elseif (! $response instanceof SymfonyResponse &&
624627
($response instanceof Arrayable ||
625628
$response instanceof Jsonable ||
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
use Orchestra\Testbench\TestCase;
4+
use Illuminate\Support\Facades\Route;
5+
use Illuminate\Contracts\Support\Responsable;
6+
7+
/**
8+
* @group integration
9+
*/
10+
class ResponsableTest extends TestCase
11+
{
12+
public function test_responsable_objects_are_rendered()
13+
{
14+
Route::get('/responsable', function () {
15+
return new TestResponsableResponse;
16+
});
17+
18+
$response = $this->get('/responsable');
19+
20+
$this->assertEquals(201, $response->status());
21+
$this->assertEquals('Taylor', $response->headers->get('X-Test-Header'));
22+
$this->assertEquals('hello world', $response->getContent());
23+
}
24+
}
25+
26+
27+
class TestResponsableResponse implements Responsable
28+
{
29+
public function toResponse()
30+
{
31+
return response('hello world', 201, ['X-Test-Header' => 'Taylor']);
32+
}
33+
}

0 commit comments

Comments
 (0)