【问题标题】:Nested REST API route validation嵌套 REST API 路由验证
【发布时间】:2018-10-11 09:54:10
【问题描述】:

我有一些这样的路线:

GET /post/1/comment/1
PUT /post/1/comment/1
POST /post/1/comment/1/reply

验证控制器中每个 API 的 post_id 和 comment_id 会产生大量重复代码。

例如:

评论控制器

function getInfo($postId, $commentId)
{
    // validate postId
    // validate commentId
    // find & return Comment
}

function update(UpdateRequest $request, $postId, $commentId)
{
    // validate postId
    // validate commentId
    // update Comment
}

function reply(CreateReplyRequest $request, $postId, $commentId)
{
    // validate postId
    // validate commentId
    // create reply for Comment
}

这里应该做些什么来减少代码重复?最佳做法是什么?

更新 1:

它在Lumen,所以不能使用Route Model Binding?路由模型绑定应该有一些性能问题吗?

【问题讨论】:

    标签: php laravel rest validation coding-style


    【解决方案1】:

    您应该创建一个中间件并验证其中的数据。

    然后在你的控制器中只返回你想要的资源。

    路线:

    /**
     * Authentification & validation middleware API Version 1
     **/
    Route::group(['middleware' => ['auth.api.v1']], function()
    {
       Route::get('infos/{postId}/{commentId}', '...Controller@getInfo');
       [...]
    });
    

    在您的中间件中:

    <?php
    
    namespace App\Http\Middleware\API\V1;
    
    use Closure;
    use Validator;
    use Input;
    use Log;
    
    class Authenticate
    {
        /**
         * Handle an incoming request and format data request
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure  $next
         * @return mixed
         */
        public function handle($request, Closure $next)
        {
            // Validating $request
            $rules = [
                'data' => ['required'],
                [...]
            ];
            $validator = Validator::make(Input::all(), $rules);
            if ($validator->fails())
            {
                Log::debug($validator->messages());
                abort(403, 'Forbidden');
            }
    
            [...]
    
            return $next($request);
        }
    }
    

    在你的控制器中:

    function getInfo($postId, $commentId)
    {
        // find & return Comment
    }
    

    【讨论】:

    • 不错。但由于它是基于查询的验证,有什么方法可以在我的控制器中使用检索到的对象吗?
    • 是的,您可以在中间件结束之前为请求添加参数:$request->request->add([myObject' => $object]); (然后你可以像这样从控制器获取它:“$request->myObject”
    【解决方案2】:

    我建议使用route model binding 这将验证模型 ID 并为您提供相应的评论或帖子模型。

    这样可以提取模型 ID 的验证。

    我现在不知道您的回复模型是如何工作的,但我猜它是一条带有 parent_message_id 属性的消息。您可以使用与评论POST /post/1/comment相同的POST端点,添加一个可选参数:

    'parent_message_id' =&gt; 'nullable|exists:comments,parent_message_id'

    【讨论】:

    • 对不起,我没有提到它的LUMEN,并且在Lumen路由模型绑定不可用。可能是为了提高性能。
    猜你喜欢
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-18
    • 1970-01-01
    • 2014-08-14
    • 1970-01-01
    • 2016-01-10
    相关资源
    最近更新 更多