-
-
Notifications
You must be signed in to change notification settings - Fork 5
Lecture 1.7: Routing, Requests and Controllers
The very first thing that you need to do when building your application is structuring your URIs in a flexible and scalable way that is agnostic of how your application files are structured. This framework does it all for you. What you need to focus your effort on is planning where the URIs should go.
A route file is provided for you /application/config/routing/web.php
. This is where your routes should be defined. There are 4 route methods available
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::delete($uri, $callback);
Your first reaction might be that HTML forms
do not support PUT
and DELETE
. True that and the framework is capable of doing that work for you. You can check here how it is done.
The most basic route provides a simple way to execute any method (through Closure) upon the definition of the route.
try {
Route::get('helloworld', function() {
echo 'Hello World';
});
} catch (Exception $e) {
echo $e->getMessage();
}
You should be able to access it by navigating to http://your-app/helloworld
in your browser. If you have not changed the name of the app folder caligrafy
then you could use http://localhost/caligrafy/helloworld
.
It is not unusual to want to capture variables from the URI to act on them. For example if you want to access all the information on a specific book, you would want the URI to be http://your-app/books/1
where 1
is the id of the book that you want.
In order to do that with this framework you need to use {variablename}
syntax:
Route::get('books/{id}', function() {
// any code would go here
});
By doing so, any value that you put after books/
will be captured and you will be able to use it in your code. So if you navigate to http://your-app/books/1
, your code will be able to capture 1. Similarly, if you replace the one with another value, your code will be able to capture that value. Later you will learn how you can fetch this value in your code.
In an MVC structure, you most likely want to route to a controller to hand off the logic to a controller class that will handle executing that logic. In order to do this, you could define a route that will call the controller:
Route::get('books', 'BookController');
This route will redirect all calls to http://your-app/books
to the controller BookController
.
You could also specify a specific method from the BookController
to execute:
Route::get('books', 'BookController@read');
This route would call the method read
from BookController
.
Later on, you will learn how to create controllers.
The Request
class provides you with the flexibility to get all the information needed about a request made to your application. The Request
class exists in the context of a successful route. In other words, if the routing is not successful then there is no easy way to have access to the Request
class and to leverage its powerful functionalities.
From the moment a route is successful, the Request
class is available for use.
- It can be accessed from the context of any
Class
created in the/application
folder by invoking a global helper method:
request();
- In the context of a
Controller
, theRequest
is a property of these classes:
use Caligrafy\Controller;
class BookController extends Controller {
public function test()
{
dump($this->request); // will return the entire request object
}
}
Learn more about
Requests
here
A Controller
is a key entity in an MVC architecture. It is the layer that is responsible for interfacing with both the Model
and the View
. It takes its input from a View
, interfaces with the Model
to either get information or add to the information, it calls upon any other logic that needs to be applied to the information and finally sends it back to the View
to be displayed.
Most of the concepts that we covered thus far - Routing
, Request
, Models
, Relationships
, Validation
, Views
- come into play together in the context of a Controller
.
-
All the controllers that you create should be in the
/application/controllers
folder. In this folder, you can organize the controllers to your convenience. If you prefer to have your controllers in a different folder, you can always do that for as long as it is within the/application
folder. -
There is no formal naming convention for a controller. We do recommend that you remain consistent.
Learn more about naming conventions here
- All the controllers that you create should extend the
Controller
class
use Caligrafy\Controller;
class BookController extends Controller {
// your code goes here
}
- The controllers that you create need to have at the very least, an
index
method. Theindex
method gets called by default when no method is specified in theRoute
.
use Caligrafy\Controller;
class BookController extends Controller {
// index method
public function index()
{
// your code goes here
}
}
- Controllers usually cover all the actions that can be taken on the
Model
that it controls. It is therefore common to have several other methods within a controller.
use Caligrafy\Controller;
class BookController extends Controller {
// index method
public function index()
{
// your code goes here
}
public function read()
{
// your code goes here
}
}
In the Routing
section, we covered the basics of how to route a request to a Controller
or to a specific method within the controller. We will summarize them herewith.
The following route will redirect all calls to http://your-app/books
to the index
method in the BookController
:
Route::get('books', 'BookController');
The following route will redirect all calls to http://your-app/books
to the read
method in BookController
:
Route::get('books', 'BookController@read');
Frameworks are meant to help organize and structure code. Some frameworks impose that a Controller
be tied to a Model
and imposes a naming convention that forces developers to have a single controller for a model.
Our framework provides the flexibility to create a controller that is independent of a model and it allows changing its context at any point using the associate
method that takes a Model
and a database table name
arguments and returns a Controller
:
public function associate(Model $model, String $tablename);`
Let's consider the books example again. Assume you have a Book
and a Publisher
models in an online library system. In a model-constrained framework, if you need to allow the users to make changes to the Publisher
model, you will need to have a dedicated PublisherController
.
In this framework, you could change the context in methods or even within the same method:
use Caligrafy\Controller;
class MyController extends Controller {
public function readBook()
{
// associate the controller with the Book model and the books table
$this->associate('Book', 'books');
// all controller methods executed below will be in the context of Book
}
public function addPublisher()
{
// associate the controller with the Book model and the books table
$this->associate('Publisher', 'publishers');
// all controller methods executed below will be in the context of Publisher
}
}
-
Methods can be created as needed in a controller provided they don't override the built-in
Controller
methods. From the moment you override these methods, the framework could behave abnormally. -
Despite the fact that there is no prescriptive way on how to organize the logic within a method, we recommend the following logical structure:
use Caligrafy\Controller;
class MyController extends Controller {
public function myMethod()
{
// Context: set the context of the controller by association with model and table
// Retrieve & Validate: fetch any parameters needed from the request when applicable and validate it
// Model: Create a model when applicable based on the retrieved data or the data to be changed
// Act: perform the action on the model
// View: return a view with the output of the action
}
}
- From the moment a
Controller
is a created as previously described, powerful built-in methods and properties are provided out of the box.
Learn more about
Controller Methods and Properties
here