Making a HTTP Request with id parameter - laravel

I have 2 projects running in two diffrent ports
In another project I have written this route
Project A
Route::get("/getBook/{id}", function ($id) {
return response()->json(BlogArticle::find($id));
});
This route will be used as an api for other projects to get the needded books.
In the other project i want to retrive the book by sending a id as a parameter {id} in the url
My approach
Route::get("/api/testing", function () {
$response = Http::get('http://127.0.0.1:900/api/getBook', [
'id' => 1
]);
return $response;
});
But nothing is being returned I am getting 404 not found error?
What am I missing?

Since the route definition is Route::get('/getBook/{id}') it means any GET request to that URL will be handled. The {id} part is a placeholder in the URL, it does not denote a query string part. Therefore you’ll have to include the ID in the URL itself:
$response = Http::get('http://127.0.0.1:900/api/getBook/1')

Related

Laravel 8 - friendly url that call multiple controllers depending on match (products, categories, pages) - How to design it?

i would like to build a route that catch clean seo friendly url and call correct controller to display page. Examples:
https://mypage.com/some-friendly-url-separated-with-dashes [PageController]
https://mypage.com/some-cool-eletronic-ipod [ProductController]
https://mypage.com/some-furniture-drawers [CategoryController]
So I have in app route:
Route::get('/{friendlyUrl}', 'RouteController#index');
Each friendly url is a unique url(string) so there is no duplicate between pages/products/categories. There is also no pattern between urls - they could be any string used in seo(only text plus dashes/ sometimes params).
Is it wise to build one db table that keeps all urls in on place with info what to call ( url | controller_name | action_name) - as an example.
Another question is - how to call different controllers depending on url used? (for above example -> RouteController catch friendly urls -finds match in db table -> then calls correct controller)
Many thanks for any help.
Have a nice day
Mark
There's two approaches you can take to this.
Proactive:
In web.php
$slugs = Product::pluck('slug');
foreach ($slugs as $slug) {
Route::get($slug, 'ProductController#index');
}
$slugs = Category::pluck('slug');
foreach ($slugs as $slug) {
Route::get($slug, 'CategoryController#index');
}
$slugs = Page::pluck('slug');
foreach ($slugs as $slug) {
Route::get($slug, 'PagesController#index');
}
Then you can determine the product in the appropriate controler via e.g.
$actualItem = Product::where('slug', request()->path())->first();
The downside to this approach is that all routes are registered on every request even if they are not used meaning you hit the database on every request to populate them. Also, routes can't be cached when using this approach.
Reactive:
In this approach you use the fallback route:
In web.php:
Route::fallback(function (Request $request) {
if (Page::where('slug', $request->path())->exists()) {
return app()->call([ PageController::class, 'index' ]);
}
if (Category::where('slug', $request->path())->exists()) {
return app()->call([ CategoryController::class, 'index' ]);
}
if (Product::where('slug', $request->path())->exists()) {
return app()->call([ ProductController::class, 'index' ]);
}
abort(404);
});
You need create a table call slugs.
Then create a unique slug (can be auto generated or specified) for each page, product, category.
slug records also have columns to get Controller and params, ex: type and id
It'd be better if you just use a prefix for each type like this:
https://mypage.com/pages/some-friendly-url-separated-with-dashes [PageController]
https://mypage.com/products/some-cool-eletronic-ipod [ProductController]
https://mypage.com/category/some-furniture-drawers [CategoryController]
Then for achieving this, create three routes like this
Route::get('pages/{friendlyUrl}', 'PageController#index');
Route::get('products/{friendlyUrl}', 'ProductController#index');
Route::get('category/{friendlyUrl}', 'CategoryController#index');
These URLs would be SEO friendly

Not able to get Route parameter - Laravel 6

I have tried multiple solution but nothing worked yet, i am trying to get route Parameter in controller that was passed from a view.
Here is how i have created the route:
Route::get('addOptions/{questionId}', 'QuestionController#addOptions')->name('addOptions');
Here is how i am passing parameter to route from view:
Add Options
And here is what i am trying to get in controller but it's returning empty array:
public function addOptions(Request $request)
{
$allParameters = $request->input(); //not working
//$allParameters = $request->all(); //not working
//$allParameters = Input::all(); //not working
return $allParameters;
}
It returns empty array [] like this.
EDIT: But url at route addOptions look like this http://127.0.0.1:8000/admin/addOptions/4 in which 4 is questionId which means parameter is being passed but not retrieved.
What am I doing wrong here? Please guide, Thanks.
You should be passing the route like this:
Add Options
as for Laravel docs. the route params are passed an array with the key referencing the param
$url = route('profile', ['id' => 1]);
To retrieve the data in your controller, you should use:
$request->route()->paremeters()
or
$request->route('parameter_name')
If you want to pass the parameter
Add Options
I think your function parameters are wrong
You are passing question id from Route So your function should be like
public function addOptions($questionId)
{
$allParameters = $questionId; // you question ID passed throught Route
return $allParameters;
}

Laravel route model binding and fallback

I am working on an api with laravel. For this, I wanna return a json response for all 404 errors. I created this fallback route and placed it at the end of the api.php:
Route::fallback(function(){
return response()->json(['message' => 'Not Found.'], 404);
})->name('api.fallback.404');
When I now enter an invalid url like /xyz I get the json response as expected.
But when I use route model binding:
Route::get('/projects/{project}', function (\App\Models\Project $project) {
return $project->toArray();
});
and try to get a non existing project (for example /projects/9999), then I get the standard laravel 404 HTML response and not my json one.
How to fix this?

How do I redirect to a URL with query parameters?

I am trying to do a redirect with query parameters, using the redirect() helper:
$link = 'https://example.com' . '?key1=value1&key2=value2';
return redirect()->to($link);
The problem is that when the $link is passed to the to() method Laravel removes the question mark leading the query string, so it turns this:
https://example.com?key1=value1&key2=value2
into this:
https://example.comkey1=value1&key2=value2
(again, notice the missing ? in the final link).
How do I make a redirect with query params appended to a custom URL?
Use:
return redirect($link);
If you want to redirect a named route with query string, use:
return redirect()->route('route_name',['key'=> $value]);
Documentation
The approved answer explains it all, according to the documentation. However, if you are still interested in finding some kind of "hard-coded" alternative:
$link = "https://example.com?key1={$value1}&key2={$value2}";
Then,
return redirect($link);
Reference
If the link is to a page on your domain, you don't need to re-write the domain name, just:
$link = "?key1=${value1}&key2=${value2}";
Laravel will automatically prepend the URL with your APP_URL (.env)
If you're building a Single Page Application (SPA) and you want to redirect to a specific page within your app from a server request, you can use the query method from the Arr helper class. Here is an example:
$result = Arr::query([
'result' => 'success',
'code' => '200'
]);
return redirect("/purchase?$result");
This will redirect the user to the /purchase page with the query parameters result=success and code=200.
For example, the final url would be:
http://example.com/purchase?result=success&code=200

laravel api with vue 2 js not returning data - could 'localhost:8000' (or '127.0.0.1:8000') be the issue?

I am using the repo https://github.com/mschwarzmueller/laravel-ng2-vue/tree/03-vue-frontend so I have 100% confidence in the reliability of the code. I can post through the laravel api endpoint through the very simple Vue client, and also through Postman. Through Postman I can retrieve the table data array, but not so in the client app. In POSTMAN:
localhost:8000/api/quotes
works just fine.
IN THE vue 2 js CLIENT APP:
methods: {
onGetQuotes() {
axios.get('http://localhost:8000/api/quotes')
.then(
response => {
this.quotes = (response.data.quotes);
}
)
.catch(
error => console.log(error)
);
}
returns nothing. returning the response to Console.log returns nothing. The Network/XHR tab shows the table data rows, but I am not sure what that means.
I know for sure that this code works for others with their unique api endpoints, which I assume may not use localhost or '127:0.0.1:1080.
Edit: in response to request for more info
public function getQuotes()
{
$quotes = Quote::all();
$response = [$quotes];
return response()->json($response, 200);
}
and the relevant route:
Route::get('/quotes', [
'uses' => 'QuoteController#getQuotes'
]);
Just to confirm: I am using verified github repo code in which the ONLY change is my api endpoint addressas mentioned in the first line of the body of this question. . Note that the Laravel back end is also derived from a related repo in Max's fine tutorial. The running code can be seen at
So I really don't think this is a coding error- but is it a configuration error due to me using local host??
EDIT: It WAS a coding error in the laravel controller as shown below
The reason your code isn't working if because you haven't provided a key for your $quotes in your controller but you're looking for it in your vue file (response.data.quotes).
[$quotes] is essentially [0 => $quotes] so when the json response comes through it be 0: [...] not quotes: [...].
To get this to work you just need to change:
$response = [$quotes];
to:
$response = ['quotes' => $quotes];
Furthermore, just an FYI, you don't need to provide the 200 in response->json() as it's the default and you can just return an array and Laravel automatically return the correct json response e.g.:
public function getQuotes()
{
$quotes = \App\Models\Artist::all();
return compact('quotes'); //<-- This is just another way of writting ['quotes' => $quotes]
}
Obviously, you don't have to if you don't want to.
Hope this helps!

Resources