So I have two models User and File, these are connected with a one-to-many relationship.
I have sorted the API routes and controllers to index all users, show specific user and index all files uploaded by that specific user. I do not know how to write the logic that will allow this route 127.0.0.1:8001/api/2/files/1 to show the first file uploaded by the 2nd user. So/2(seconduser)/files(shows all)/1(shows only 1 file)
This is my API code:
Route::group(["prefix" => "/"], function () { Route::get("", [Users::class, "index"]); //show all users Route::group(["prefix" => "{user}"], function () { Route::get("", [Users::class, "show"]); //show specific user Route::group(["prefix" => "/files"], function () { Route::get("", [Files::class, "index"]); //show all files Route::group(["prefix" => "{file}"], function () { Route::get("", [Files::class, "show"]); //trying to show specific file }); }); }); });
Files Controller
<?php namespace AppHttpControllersAPI; use AppHttpControllersController; use IlluminateHttpRequest; use AppModelsUser; use AppModelsFile; class Files extends Controller { /** * Display a listing of the resource. * * @return IlluminateHttpResponse */ public function index(User $user) { return $user->files; } /** * Display the specified resource. * * @param int $id * @return IlluminateHttpResponse */ public function show(User $user, File $file) { } }
Users Controller
<?php namespace AppHttpControllersAPI; use AppHttpControllersController; use IlluminateHttpRequest; use AppModelsUser; class Users extends Controller { /** * Display a listing of the resource. * * @return IlluminateHttpResponse */ public function index() { return User::all(); } /** * Display the specified resource. * * @param int $id * @return IlluminateHttpResponse */ public function show(User $user) { return $user; } }
Advertisement
Answer
So here’s what a typical route declaration would look like. Note the user ID is not relevant to the file request, so the files endpoint is made separate from the users endpoint.
Route::get("/users", [Users::class, "index"]); Route::get("/users/{user}", [Users::class, "show"]); Route::get("/users/{user}/files", [Files::class, "index"]); Route::get("/files/{file}", [Files::class, "show"]);
And then in your controller methods, you’re simply returning a list or a single item, mostly as in your original code. Note if you’re returning API data, you should explicitly return JSON.
<?php namespace AppHttpControllersAPI; use AppHttpControllersController; use IlluminateHttpRequest; use AppModelsUser; use AppModelsFile; class Files extends Controller { /** * Display a listing of the resource. * * @return IlluminateHttpJsonResponse */ public function index(User $user) { return response()->json($user->files); } /** * Display the specified resource. * * @param int $id * @return IlluminateHttpJsonResponse */ public function show(File $file) { return response()->json($file); // or perhaps something like this? return response() ->download($file->path, $file->name, ["Content-Type" => $file->type]); } }
<?php namespace AppHttpControllersAPI; use AppHttpControllersController; use IlluminateHttpRequest; use AppModelsUser; class Users extends Controller { /** * Display a listing of the resource. * * @return IlluminateHttpJsonResponse */ public function index() { return response()->json(User::all()); } /** * Display the specified resource. * * @param int $id * @return IlluminateHttpJsonResponse */ public function show(User $user) { return response()->json($user); } }