-
-
Save taylorotwell/68f614deb9538f2e30108c2698266fda to your computer and use it in GitHub Desktop.
<?php | |
/* | |
|-------------------------------------------------------------------------- | |
| Application Routes | |
|-------------------------------------------------------------------------- | |
| | |
| Here is where you can register all of the routes for an application. | |
| It's a breeze. Simply tell Laravel the URIs it should respond to | |
| and give it the controller to call when that URI is requested. | |
| | |
*/ | |
use Illuminate\Http\Request; | |
use Illuminate\Routing\Controller; | |
use Illuminate\Support\Collection; | |
use Illuminate\Database\Connection; | |
use Illuminate\Contracts\Routing\ResponseFactory; | |
/** | |
* Resolve an action out of the container and call it, injecting method dependencies. | |
*/ | |
function marshal($action) | |
{ | |
return App::call([App::make($action), 'handle']); | |
} | |
/** | |
* A repository... | |
*/ | |
class PostRepository | |
{ | |
protected $connection; | |
public function __construct(Connection $connection) | |
{ | |
$this->connection = $connection; | |
} | |
public function all() | |
{ | |
return $this->connection->table('posts')->get(); | |
} | |
} | |
/** | |
* The responder... | |
*/ | |
class ListPostsResponder | |
{ | |
protected $response; | |
public function __construct(ResponseFactory $response) | |
{ | |
$this->response = $response; | |
} | |
public function handle(Collection $data) | |
{ | |
if (count($data) === 0) { | |
return $this->response->make('Not found.', 404); | |
} else { | |
return $this->response->view('posts.index', ['posts' => $data->all()]); | |
} | |
} | |
} | |
/** | |
* The action... | |
*/ | |
class ListPosts | |
{ | |
public function handle(Request $request, | |
ListPostsResponder $responder, | |
PostRepository $posts) | |
{ | |
return $responder->handle( | |
$posts->all() | |
); | |
} | |
} | |
/** | |
* The route... | |
*/ | |
$router->get('/posts', function () { | |
return marshal(ListPosts::class); | |
}); |
For what it's worth, I extended Laravel's router to support an invoke
parameter in the route definition, so that I could define invokable Action classes without needing to specify the @__invoke
method suffix on every item.
$router->get('posts', [
'as' => 'posts.list',
'invoke' => ListPosts::class,
]);
It would be nice if the router could determine if an item passed is callable
rather than looking for only \Closure
so extending is not needed, however I understand some of the holes or gotchas that come with doing so.
@pmjones your link was broken: http://pmjones.io/adr/
@jacobhenke fixed; thanks!
I got prompted to visit this gist without much context.
Was there any doubt that Laravel could not conform to ADR?
@cryode Any chance you could share this code?
I'm working on the same thing.
I read somewhere that callables were fixed in 5.3 but they definitely don't work in 5.7.
ADR makes you create a separate route for everything, route config becomes a mess.
(As an aside, you don't need an else if you return in the first half of the conditional: https://gist.github.com/taylorotwell/68f614deb9538f2e30108c2698266fda#file-gistfile1-php-L63)