Laravel HTTP Client dynamic call HTTP Method - laravel

I want to make all requests dynamic rather than defining Http in each function followed by httpMethod like this.
Http::post()
Http::put()
Http::delete()
what i tried.
function send($method, $url) {
Http::withToken($token)->{$method}($url)
}
function x() {
return $this->send('GET', 'url')
}
My code above works fine and i dont know if call a function from variable output like {$method} is best practice. but I want something similar like Guzzle.
(new Client)->request($method, $url, $options)

you need to accept that param like
function send($method,$url) {
retrun Http::withToken($token)->{$method}($url)
}

if you take a look at the source code here https://github.com/illuminate/http/blob/a28981924d318272053b87712740868d9b44899e/Client/PendingRequest.php laravel is using Guzzle. so basicly Http Client is Guzzle.
and every function like POST PUT etc call a function name send
so you can just direct call send function like this.
Http::withToken($token)
->send('POST', 'url', [
'headers' => [...]
'form_params' => [
...
]
])

Related

Laravel request->all() is empty

In Laravel 8, $request->all() is not showing dynamic path parameters.
Steps to reproduce:
Start a new Laravel project with composer, Laravel version 8.61.0.
Define a route in routes/api.php as follows:
Route::get('/first/{first}/second/{second}', function (Request $request) {
return $request->all();
});
Run php artisan serve and direct the browser to http://localhost:8000/api/first/hello/second/world
Expect something like the following response: {"first":"hello","second":"world"}. Instead we simply see [].
Change the route to:
Route::get('/first/{first}/second/{second}', function (Request $request) {
return [
'first'=>$request->first,
'second'=>$request->second,
];
});
Then we see the expected {"first":"hello","second":"world"}
So...why isn't $request->all() giving me this response?
I looked at Laravel doc
Retrieving All Input Data
You may retrieve all of the incoming request's input data as an
array using the all method. This method may be used regardless of
whether the incoming request is from an HTML form or is an XHR
request
Means $request->all() equal to $request->input('name', 'email', ....)
instead of $request->all() you can try this
Route::get('/first/{first}/second/{second}', function (Illuminate\Http\Request $request, $first, $second) {
return [
'first'=> $first,
'second'=> $second,
];
});
UPDATE
You can do it too with (splat operator in PHP)
Route::get('/first/{first}/second/{second}', function (Illuminate\Http\Request $request, ...$all) {
return $all;
});
// returns
[
"hello",
"world"
]
I hope this helped you,
Happy Coding.
Have you tried dd($request->all()) statement in Controller, not in closure. In previous Laravel version (version 5 or version 7), that state works in that versions.
don't know why $request->all() is empty, but I used $request->getContent() and it returned the data in the body of the request I was looking for.
Credit:
Laravel empty request

How to validate params in REST Lumen/Laravel request?

Route:
$app->get('/ip/{ip}', GeoIpController::class . '#show');
How to validate ip's properly? I've tried to inject Request object in show method, but wasn't able to solve this. I want to stick with REST, so using URL parameters is not solution for me. I use it for API purposes, so status code as response would be appropriate.
Also tried that way:
$app->bind('ip', function ($ip) {
$this->validate($ip, [
'ip' => 'required|ip',
]);
});
EDIT:
The answer below is correct, I've found more info about requests in documentation:
Form requests are not supported by Lumen. If you would like to use form requests, you should use the full Laravel framework.
In other words, you cannot use custom requests via injection in constructors in Lumen.
The validate method takes the request object as the first parameter. Since you're passing the ip in the route, you need to create a custom validator.
public function show($ip)
{
$data = ['ip' => $ip];
$validator = \Validator::make($data, [
'ip' => 'required|ip'
]);
if ($validator->fails()) {
return $validator->errors();
}
return response()->json(['All good!']);
}
Edit : This is all laravel does under the hood. You could basically you this function directly to validate the ip and save a lot of effort.
protected function validateIp($ip)
{
return filter_var($ip, FILTER_VALIDATE_IP) !== false;
}

How to change response in Laravel?

I have RESTful service that is available by endpoints.
For example, I request api/main and get JSON data from server.
For response I use:
return response()->json(["categories" => $categories]);
How to control format of response passing parameter in URL?
As sample I need this: api/main?format=json|html that it will work for each response in controllers.
One option would be to use Middleware for this. The below example assumes that you'll always be returning view('...', [/* some data */]) i.e. a view with data.
When the "format" should be json, the below will return the data array passed to the view instead of the compiled view itself. You would then just apply this middleware to the routes that can have json and html returned.
public function handle($request, Closure $next)
{
$response = $next($request);
if ($request->input('format') === 'json') {
$response->setContent(
$response->getOriginalContent()->getData()
);
}
return $response;
}
You can use for this Response macros. For example in AppServiceProvider inside boot method you can add:
\Response::macro('custom', function($view, $data) {
if (\Request::input('format') == 'json') {
return response()->json($data);
}
return view($view, $data);
});
and in your controller you can use now:
$data = [
'key' => 'value',
];
return response()->custom('your.view', $data);
If you run now for example GET /categories you will get normal HTML page, but if you run GET /categories?format=json you will get Json response. However depending on your needs you might need to customize it much more to handle for example also redirects.
With your format query parameter example the controller code would look something like this:
public function main(Request $request)
{
$data = [
'categories' => /* ... */
];
if ($request->input('format') === 'json') {
return response()->json(data);
}
return view('main', $data);
}
Alternatively you could simply check if the incoming request is an AJAX call via $request->input('format') === 'json' with $request->ajax()

How to write on route to receive request from external laravel project

$client = new Client();
$response =
$client->GET('http://XXX.XX.XX.XX/eDeskApi/module/SOMEFUNCTION',
[
'json' => ['foo' => 'bar']
]);
This is how i'm sending a request to external LARAVEL api.
I just want to know what do i need to write in laravel api router to get something return when i send this request.
Currently i have the following code on laravel api router
Route::GET('module/url', 'Nameof Controller#NameOfMethhod');
And in controller looks like:
public function GetApplicationModuleList()
{
echo 'something';
//i want to print the parameter value which i just sent by above mention request.
}
You need to change your request from GET to POST if you want to send some request body there.
Also your function should take an argument of:
Illuminate\Http\Request type.
After that you can access you request body by doing:
$request -> all();

Laravel - Change URL parameters using GET

I have RESTful API built on Laravel.
Now I'm passing parameter like
http://www.compute.com/api/GetAPI/1/1
but I want to pass parameter like
http://www.compute.com/api/GetAPI?id=1&page_no=1
Is there a way to change Laravel routes/functions to support this?
you can use link_to_route() and link_to_action() methods too.
(source)
link_to_route take three parameters (name, title and parameters). you can use it like following:
link_to_route('api.GetAPI', 'get api', [
'page_no' => $page_no,
'id' => $id
]);
If you want to use an action, link_to_action() is very similar but it uses action name instead of route.
link_to_action('ApiController#getApi', 'get api', [
'page_no' => $page_no,
'id' => $id
]);
href text
with these methods anything after the expected number of parameters is exceeded, the remaining arguments will be added as a query string.
Or you can use traditional concatination like following:
create a route in routes.php
Route::get('api/GetAPI', [
'as' => 'get_api', 'uses' => 'ApiController#getApi'
]);
while using it append query string like this. you can use route method to get url for required method in controller. I prefer action method.
$url = action('ApiController#getApi'). '?id=1&page_no=1';
and in your controller access these variables by following methods.
public function getApi(Request $request) {
if($request->has('page_no')){
$page = $request->input('page_no');
}
// ...your stuff
}
Or by Input Class
public function getApi() {
if(Input::get('page_no')){
$page = Input::get('page_no');
}
// ...your stuff
}
Yes you can use those parameters, then in your controllers you can get their values using the Request object.
public function index(Request $request) {
if($request->has('page_no')){
$page = $request->input('page_no');
}
// ...
}

Resources