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);
}
}