Laravel routes with multiple optional parameters - php

I am building a RESTful api using Laravel. I am confused on how to do the routing.
I have the following api controller
class APIController extends BaseController{
public function sendMsg($authid, $roomid, $msg){
}
public function getMsg($roomid, $timestamp){
}
}
The URL format I want this to be accessible looks like this:
http://example.com/api/{functionName}/{parameter1}/{parameter2}/.../
Here, in the first parameter, I will have the function name which should map to the function in the controller class and following that the parameters the controller needs.
For example To access the sendMsg() function, the url should look like this:
http://example.com/api/sendMsg/sdf879s8/2/hi+there+whats+up
To access the getMsg() function, the url should look like
http://example.com/api/getMsg/2/1395796678
So... how can I write my routes so that it can handle the dynamic number and different parameters need?
I can write one route for each function name like so:
Route::get('/api/sendmsg/{authid}/{msg}', function($authid, $msg){
//call function...
});
and same for the other function. This if fine but is there a way to combine all function to the APIController in one route?

Yes, you can combine all the function to your APIController in one route by using a resourceful controller which is best suited for building an API:
Route::resource('api' ,'APIController');
But, technically, it's not one route at all, instead Laravel generates multiple routes for each function, to check routes, you may run php artisan routes command from your command prompt/terminal.
To, create a resourceful controller you may run the following command from your command line:
php artisan controller:make APIController
This will create a controller with 6 functions (skeleton/structure only) and each function would be mapped to a HTTP verb. It means, depending on the request type (GET/POST etc) the function will be invoked. For example, if a request is made using http://domain.com/api using GET request then the getIndex method will be invoked.
public function getIndex()
{
// ...
}
You should check the documentation for proper understanding in depth. This is known as RESTful api.

Related

How to access to laravel routing resource methods?

I am using laravel to have access to my database. I have used the command php artisan make:controller CategoriesController --resource in the terminal to create a class where I can access different methods in one route.
The routing code for the class is: Route::apiResource("categories", CategoriesController::class);. With /categories I can get to the index() method (via get), where I can show my table values. But I do not know how I can use other methods. For example I have created test() with a simple return ["Result"=>"Working"].
I have tried /categories/test /categoriestest /categories%test but I can not show the result from test().
Simple routing works fine when I use specific routes for every method, but I want to make a more clear code so I would like to use the --resource to only have one route.

Laravel controller route

In Laravel 5.1 I was able to create following route:
Route::controller('posts', 'PostsController');
It was very handy, since I could use methods depending on request type:
public function getCreate()
{
// method for getting
}
public function postCreate()
{
// method for creating
}
In Laravel 5.5 it appears that this functionality (HTTP Controllers) has been removed(?) and replaced by HTTP Requests.
Requests are nice, but not that handy.. and it offers way more methods than I need.
Is there a possibility to keep using request-related method names for controllers in Laravel 5.5?
I think you can use Resource Route
Resource Controllers
Laravel resource routing assigns the typical "CRUD" routes to a controller with a single line of code. For example, you may wish to create a controller that handles all HTTP requests for "photos" stored by your application. Using the make:controller Artisan command, we can quickly create such a controller:
php artisan make:controller PhotoController --resource
This command will generate a controller at app/Http/Controllers/PhotoController.php. The controller will contain a method for each of the available resource operations.
Next, you may register a resourceful route to the controller:
Route::resource('photos', 'PhotoController');
This single route declaration creates multiple routes to handle a variety of actions on the resource. The generated controller will already have methods stubbed for each of these actions, including notes informing you of the HTTP verbs and URIs they handle.
Actions Handled By Resource Controller
Ref:
https://laravel.com/docs/5.5/controllers#resource-controllers
Route::controller() was eliminated after Laravel 5.3
Route::resource() is very specific to exactly, only create for you and let you access the seven methods to CRUD an object
If you want to create your own views, I believe you have to define all them with Route::get(), Route::post(), etc. in the routes/web file

PHP Silex - Service Controller - passing a parameter

According to :
Silex - Service Controller Doc
I can define a route like this (after a couple of extra code of corse):
$app->get('/posts.json', "posts.controller:indexJsonAction");
But ... how can I pass the url used to the indexJsonAction function?
You should be mapping that directly to the route, such as:
$app->get('/posts.json/{param1}/{param2}, 'posts.controller:indexJsonAction');
This way, in your controller, you can expect those parameters:
public function indexJsonAction($param1, $param2) {
//now you have access to these variables.
}
Furthermore, silex uses Symfony's request under the hood, so you could also just inject the Request into the controller and get any input from the Request;
public function indexJsonAction(Request $request) {
// use $request->get('param1'); etc
}

Missing argument 1 for MyController in RESTful application

I am developing app in laravel (REST server), using Basic Auth. Using Postman, all GET requests I have implemented seem to work, but unfortunately POST requests not.
routes.php:
Route::post('my/action', 'MyController#postMyAction');
My Controller:
public function __construct()
{
$this->middleware('auth.basic.once');
}
public function postMyAction($request)
{
// some logic here
}
The problem is, that this way, after setting credentials and some params in Postman, following exception appears:
Missing argument 1 for
App\Http\Controllers\MyController::postMyAction()
Does anybody knows how to put request into post-processing function defined in routes?
Thanks in advance.
Laravel provides dependency injection for controller methods, however you need to typehint exactly what you want so Laravel knows what to inject:
public function postMyAction(\Illuminate\Http\Request $request)
{
// Now $request is available
Now Laravel knows you want an instance of Illuminate\Http\Request and it will give it to you.
Of course you can also stick use Illuminate\Http\Request; at the top of your controller then just typehint Request $request as the argument.

Laravel call function from another controller during validation for Paypal payment

I have a registration form (using Laravel 5 here), which upon submit calls BusinessController#postRegister
public function postRegister(Requests\RegisterBusinessRequest $request)
{
#1. get input, fill new class and save to database
#2. call PayPayController#postBusinessProvider
}
What I'm trying to do is call my PayPalController function to process payment, I've tried return Redirect::action('PayPalController#postBusinessProvider'); but that doesn't seem to work.
Do I have to simply have to create a route to call a function from another Controller or is there another way without creating a route? Or should I just put my PayPal code within the postRegister function, I figured cleaner to seperate?
In MVC model (and in Laravel) a controller will not call another controller in one request. To make your controller business simpler, you can use one of these two options:
Option 1
Separate a controller logic into small parts, each part is solve by a private or protected method of the same controller class. So that your controller will be something like this:
public function postRegister(Requests\RegisterBusinessRequest $request)
{
$this->_validateInput();
$this->_processInput();
$this->_doWithPaypal();
}
Option 2
Create a repository class and to all complicated logic here. In your controller method, get the repository instance and pass your input data as the argument for this instance methods. You can see and example at zizaco/confide package. Your controller will something like this:
public function postRegister(Requests\RegisterBusinessRequest $request)
{
$repo = App::make('PaypalRepositoryClass');
// process your input
// ...
// ...
$repo->paypalBusiness($data);
}

Categories