如何在 Laravel 中制作 REST API 第一个 Web 应用程序 [英] How to make a REST API first web application in Laravel

查看:22
本文介绍了如何在 Laravel 中制作 REST API 第一个 Web 应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 Laravel 中创建一个 API 第一个应用程序.我不知道这样做的最佳方法是什么,我将解释我想要做什么,但请随时回答如何以不同的方式做到这一点.

I want to make an API first application in Laravel. I don't know what is the best approach to do this, I will explain what I am trying to do, but please feel free to give answers how to do this in a different way.

我不希望我的所有前端都用 javascript 编写并使用 angular.js 或类似的东西解析 API 的 JSON 输出.我希望我的 Laravel 应用程序生成 HTML 视图.我正试图走上拥有两个控制器的道路,一个用于 API,一个用于 Web.对于 show User 操作,我的 routes.php 如下所示:

I don't want all my frontend to be written in javascript and parse the JSON output of the API with angular.js or something similar. I want my Laravel application to produce the HTML views. I am trying to go down the road of having two controllers one on for the API and one for the web. For the show User action my routes.php looks like this:

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

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

所以 /user 会带我到 WebUserController/api/user 会带我到 UserController.现在我想把我所有的逻辑放在 API UserController 中,并从 WebUserController 调用它的操作.这是他们两个的代码:

So /user will take me to WebUserController and /api/user will take me to the UserController. Now I want to put all my logic in the API UserController, and call its actions from the WebUserController. Here is the code for both of them:

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

WebUserController 中,我可以使用 getData() 获取响应的 json 内容,但是我无法获取标题和状态代码(它们是 Illuminate\Http\JsonResponse 的受保护属性.

In the WebUserController I am able to get the json content of the response with getData(), but I am not able to get the headers and status code (they are protected properties of Illuminate\Http\JsonResponse).

我认为我的方法可能不是最好的,所以我愿意接受关于如何制作这个应用程序的建议.

I think that my approach might not be the best, so I am open to suggestions how to make this app.

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

EDIT: The question how to get the headers and status of the response has been answered by Drew Lewis, but I still think that there might be a better way how to design this

推荐答案

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

You should utilize the Repository / Gateway design pattern: please see the answers here.

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

For example, when dealing with the User model, first create a User Repository. The only responsibility of the user repository is to communicate with the database (performing CRUD operations). This User Repository extends a common base repository and implements an interface containing all methods you require:

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)

}

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

Then, create a service provider, which binds your user repository interface to your eloquent user repository. Whenever you require the user repository (by resolving it through the IoC container or injecting the dependency in the constructor), Laravel automatically gives you an instance of the Eloquent user repository you just created. This is so that, if you change ORMs to something other than eloquent, you can simply change this service provider and no other changes to your codebase are required:

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

}

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

Next, create a User Gateway, who's purpose is to talk to any number of repositories and perform any business logic of your application:

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 控制器.此控制器与您的用户网关对话:

Finally, create your User web controller. This controller talks to your User Gateway:

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

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

    }
}

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

By structuring the design of your application in this way, you get several benefits: you achieve a very clear separation of concerns, since your application will be adhering to the Single Responsibility Principle (by separating your business logic from your database logic) . This enables you to perform unit and integration testing in a much easier manner, makes your controllers as slim as possible, as well as allowing you to easily swap out Eloquent for any other database if you desire in the future.

例如,如果从 Eloquent 更改为 Mongo,您唯一需要更改的是服务提供者绑定以及创建一个实现 UserRepository 接口的 MongoUserRepository.这是因为存储库是唯一与您的数据库对话的东西 - 它不知道其他任何东西.因此,新的 MongoUserRepository 可能类似于:

For example, if changing from Eloquent to Mongo, the only things you need to change are the service provider binding as well as creating a MongoUserRepository which implements the UserRepository interface. This is because the repository is the only thing talking to your database - it has no knowledge of anything else. Therefore, the new MongoUserRepository might look something like:

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:

And the service provider will now bind the UserRepository interface to the new MongoUserRepository:

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

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

Throughout all your gateways you have been referencing the UserRepository, so by making this change you're essentially telling Laravel to use the new MongoUserRepository instead of the older Eloquent one. No other changes are required.

这篇关于如何在 Laravel 中制作 REST API 第一个 Web 应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆