Home
Quick start
Documentation
Forum
GitHub
Home
Quick start
Documentation
Forum
GitHub
  • Quick Start

    • Introduction
    • Why Phico
    • Installation
  • Example app

    • Scaffolding
    • Routes
    • Requests
    • Responses
    • Events
  • Phico

    • CLI
    • Config
    • Container
    • Filesystem
    • Logger
    • Middleware
    • Request
    • Response
    • Router
    • Support
    • View
  • Libraries

    • Authentication
    • Cache
    • CDN
    • Database
    • Http client
    • Locale
    • Mailer
    • Profiler
    • Query
    • Queue
    • Validation
    • Session
    • View
  • Works

    • Introduction

Routes

Routes connect your app urls with your Action or Controller classes.

Actions or Controllers

The traditional approach in web development is often the MVC (Model, View, Controller) pattern. In this approach the responsibility for managing the Request happens in the Controller, handling things like authorisation and validation. Data procesing tends to happen in the Model such as fetching and saving from persistence. And the user is given feedback via the View which combines templates with data to give useful feedback.

Actions and Controllers do exactly the same thing, the main difference is architectural. A Controller may contain many methods relating to each url in a particular module of code. Whereas an Action only ever handles one method (GET, POST etc..) in a RESTful API this may be preferred.

MVC vs ADR

While MVC (Model View Controller) is probably the default approach, ADR (Action Domain Response) has it's adherants. For more information on ADR read the original article by Paul M Jones.

Phico does not push an architectural style on your app.

The disadvantage of ADR is an increased number of classes in your app, however this does enable the developer to get a good overview of the app by checking the list of classes in the Actions folder.

Actions

To connect a route to an Action class (which must have an __invoke method) just provide the class name e.g. BrowseAction::class:

// app/Blog/routes.php

namespace Blog\Actions;

$routes->group('/blog', function ($group) {
    $group->get('/', BrowseAction::class)->name('blog.browse');
    $group->get('/{slug}', ShowAction::class)->name('blog.show');
});

The Action class could look something like this:

<?php

namespace Blog\Actions;

class BrowseAction
{
    public function __construct(
        protected PostsRepository $posts,
    ) {
        $this->posts = $posts;
    }

    public function __invoke(Request $request): Response
    {
        return response()->json([
            'status' => 'ok',
            'posts' => $this->posts->fetch(
                $request->uri()->param("page")
            ),
        ]);
    }
}

Controllers

Connect a route to a Controller class by providing the controller and method name separated by an '@' symbol.

// app/Blog/routes.php

$routes->group('/blog', function ($group) {
    $group->get('/', "\Blog\BlogController@browse")->name('blog.browse');
    $group->get('/{slug}', "\Blog\BlogController@show")->name('blog.show');
});

The Controller method will receive the Request instance and should return a Response.

<?php

namespace Blog;

class BlogController
{
    public function browse(Request $request): Response
    {
        return response()->json([
            'status' => 'ok',
            'posts' => $this->posts->fetch(
                $request->uri()->param("page")
            ),
        ]);
    }
    public function show(Request $request): Response
    {
        return response()->json([
            'status' => 'ok',
            'post' => $this->posts->fetchBySlug(
                $request->route()->param("slug")
            ),
        ]);
    }
}
Last Updated:
Contributors: indgy
Prev
Scaffolding
Next
Requests