如何在Laravel中创建REST API第一个Web应用程序

Mar*_*ski 28 php api rest controller laravel

我想在Laravel中创建一个API第一个应用程序.我不知道这样做的最佳方法是什么,我会解释我想要做什么,但请随意以不同的方式给出答案.

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

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

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

所以/user将带我去WebUserController,/api/user并带我去UserController.现在我想将所有逻辑放在API中UserController,并从中调用它的动作WebUserController.以下是两者的代码:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

see*_*RMS 42

您应该使用Repository/Gateway设计模式:请在此处查看答案.

例如,在处理User模型时,首先创建一个User Repository.用户存储库的唯一责任是与数据库通信(执行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)

}
Run Code Online (Sandbox Code Playgroud)

然后,创建一个服务提供程序,它将您的用户存储库接口绑定到您的eloquent用户存储库.每当您需要用户存储库(通过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
        );
    }

}
Run Code Online (Sandbox Code Playgroud)

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

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

}
Run Code Online (Sandbox Code Playgroud)

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

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

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

    }
}
Run Code Online (Sandbox Code Playgroud)

通过以这种方式构建应用程序的设计,您可以获得以下几个好处:您可以非常清楚地分离关注点,因为您的应用程序将遵循单一责任原则(通过将业务逻辑与数据库逻辑分离).这使您能够以更轻松的方式执行单元和集成测试,使您的控制器尽可能轻薄,并且如果您希望将来可以轻松地将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
    }

    ...

}
Run Code Online (Sandbox Code Playgroud)

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

 $this->app->bind(
        'lib\Repositories\UserRepository',       
        'lib\Repositories\MongoUserRepository'
);
Run Code Online (Sandbox Code Playgroud)

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

  • 太多的锅炉板只是为了不太可能改变ORM的情况. (6认同)

Nya*_*tut 7

您应该使用Repository进行此设计.

示例 -

//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()));
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这看起来很好很简单,每个模型只有一个额外的类。 (2认同)