如何在Laravel中制作REST API的第一个Web应用程序

2022-08-30 14:50:31

我想在Laravel中制作一个API第一个应用程序。我不知道最好的方法是什么,我会解释我想要做什么,但请随时给出如何以不同的方式做到这一点的答案。

我不希望我所有的前端都是用javascript编写的,并用angular.js或类似的东西来解析API的JSON输出。我希望我的Laravel应用程序生成HTML视图。我正在尝试让两个控制器,一个用于API,一个用于Web。对于显示“用户操作我的路由.php如下所示:

# the web controller
Route::controller('user', 'WebUserController');

# the api controller 
Route::group(array('prefix' => 'api'), function() {
    Route::resource('user', 'UserController');
});

所以会带我去,并会带我去.现在我想把我所有的逻辑放在API中,并从中调用它的操作。以下是它们两者的代码:/userWebUserController/api/userUserControllerUserControllerWebUserController

class UserController extends BaseController 
{
    public function show($id)
    {
        $user = User::find($id);
        return Response::json(array('success'=>true,'user'=>$user->toArray()));
    }
}

class WebUserController extends UserController 
{
    public function getView($id) 
    {
         # call the show method of the API's User Controller
         $response =  $this->show($id);
         return View::make('user.view')->with('data', $response->getData());
    }
}

在 中,我能够获取响应的 json 内容,但我无法获取标头和状态代码(它们是 的受保护属性)。WebUserControllergetData()Illuminate\Http\JsonResponse

我认为我的方法可能不是最好的,所以我对如何制作这个应用程序的建议持开放态度。

编辑:如何获取响应的标题和状态的问题已经由Drew Lewis回答,但我仍然认为可能有更好的方法来设计这个


答案 1

您应该使用存储库/网关设计模式:请参阅此处的答案。

例如,在处理用户模型时,首先创建一个用户存储库。用户存储库的唯一职责是与数据库通信(执行 CRUD 操作)。此用户存储库扩展了一个公共基础存储库,并实现了一个包含您需要的所有方法的接口:

class EloquentUserRepository extends BaseRepository implements UserRepository
{
    public function __construct(User $user) {
        $this->user = $user;
    }


    public function all() {
        return $this->user->all();
    }

    public function get($id){}

    public function create(array $data){}

    public function update(array $data){}

    public function delete($id){}

    // Any other methods you need go here (getRecent, deleteWhere, etc)

}

然后,创建一个服务提供程序,它将用户存储库界面绑定到雄辩的用户存储库。每当您需要用户存储库(通过 IoC 容器解析它或在构造函数中注入依赖项)时,Laravel 都会自动为您提供刚刚创建的 Eloquent 用户存储库的实例。这样,如果您将 ORM 更改为雄辩以外的其他内容,则只需更改此服务提供程序,而无需对代码库进行其他更改:

use Illuminate\Support\ServiceProvider;

class RepositoryServiceProvider extends ServiceProvider {

    public function register() {
        $this->app->bind(
            'lib\Repositories\UserRepository',        // Assuming you used these
            'lib\Repositories\EloquentUserRepository' // namespaces
        );
    }

}

接下来,创建一个用户网关,其目的是与任意数量的存储库通信并执行应用程序的任何业务逻辑:

use lib\Repositories\UserRepository;

class UserGateway {

    protected $userRepository;

    public function __construct(UserRepository $userRepository) {
        $this->userRepository = $userRepository;
    }

        public function createUser(array $input)
        {
            // perform any sort of validation first
            return $this->userRepository->create($input);
        }

}

最后,创建用户 Web 控制器。此控制器与您的用户网关通信:

class UserController extends BaseController 
{
    public function __construct(UserGatway $userGateway)
    {
        $this->userGateway = $userGateway;
    }

    public function create()
    {
        $user = $this->userGateway->createUser(Input::all());

    }
}

通过以这种方式构建应用程序的设计,您可以获得几个好处:您可以实现非常明确的关注点分离,因为您的应用程序将遵循单一责任原则(通过将业务逻辑与数据库逻辑分开)。这使您能够以更简单的方式执行单元和集成测试,使您的控制器尽可能纤薄,并允许您在将来需要时轻松地将Eloquent换成任何其他数据库。

例如,如果从 Eloquent 更改为 Mongo,您唯一需要更改的就是服务提供程序绑定以及创建实现 UserRepository 接口的 MongoUserRepository。这是因为存储库是唯一与您的数据库通信的东西 - 它不了解任何其他内容。因此,新的MongoUserRepository可能看起来像这样:

class MongoUserRepository extends BaseRepository implements UserRepository
{
    public function __construct(MongoUser $user) {
        $this->user = $user;
    }


    public function all() {
        // Retrieve all users from the mongo db
    }

    ...

}

服务提供商现在将UserRepository接口绑定到新的MongoUserRepository:

 $this->app->bind(
        'lib\Repositories\UserRepository',       
        'lib\Repositories\MongoUserRepository'
);

在所有网关中,您一直在引用UserRepository,因此通过进行此更改,您实际上是在告诉Laravel使用新的MongoUserRepository而不是旧的Eloquent。无需其他更改。


答案 2

您应该使用存储库进行此设计。

示例 -

//UserRepository Class
class UserRepository {
    public function getById($id)
    {
      return User::find($id);
    }
}

// WebUser Controller
class WebUserController extends BaseController {
    protected $user;

    public function __construct(UserRepository $user)
    {
        $this->user = $user;
    }

    public function show($id)
    {
        return View::make('user.view')->with('data', $this->user->getById($id));
    }
}

// APIUser Controller
class UserController extends BaseController {
    protected $user;

    public function __construct(UserRepository $user)
    {
        $this->user = $user;
    }

    public function show($id)
    {
        $data =>$this->user->getById($id);
        return Response::json(array('success'=>true,'user'= $data->toArray()));
    }
}

推荐