2016-11-13 35 views
0

我試圖安裝使用超薄框架版本3的API項目,我不知道是誰發的PSR-7和標記響應對象爲不可變的,我沒有看到任何在那裏使用(恕我直言,請解釋我,如果我錯了)。當它很苗條2時,事情變得更容易。現在我在很長一段時間後回到了苗條。具有slimframework是不可變的響應麻煩

我有一個方法後的路線,我得到的數據,並保存到數據庫中,我嘗試發送201響應代碼。所有的示例和文檔都向您展示瞭如何在index.php文件本身中更改響應代碼,但是我試圖從響應構建器中更改它,我嘗試使用工廠模式來提供不同的響應。問題是響應代碼始終保持200,無論我從響應構建器類調用什麼函數。我嘗試了很多論壇和不同的瘦身方式,但仍然無法將其拉高。我幾乎決定放棄PSR 7路由器的實施,並實施我自己的路由解決方案。但我記得不要再重新發明輪子,所以我作爲最後的嘗試來到這裏。以下是代碼。

路線定義

$app->post('/users', function(ServerRequestInterface $req, ResponseInterface $res) { 
    $data = $req->getParsedBody(); 
    $model = new \Apex\Models\User(ApexDB::getInstance()); 
    $jsonBuilder = ApexResponse::getBuilder('JSON', $res); 
    $control = new \Apex\Controllers\User($model, $jsonBuilder); 
    $control->create($data); 

}); 

控制方法(抽象的,我只是將其設置)

public function create($data) { 
     if($this->model->save($data)) { 
      $this->response->build($data,201); 
     } else { 
      $this->response->build('error',400); 
     } 
    } 

的JSON建設者

class JSONBuilder implements Response 
{ 
    public $response; 

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

    public function build($data, $status) 
    { 
     $response = $this->response->withJSON($data,$status); 
     return $response; 
    } 
} 

任何人都可以點我在正確的方向?

回答

1

使用一成不變的對象進行請求和響應的PSR-7決定在元文檔的Why value objects?部進行了說明。

使用Slim 3,您必須始終從控制器方法返回一個Response實例。

$app->post('/users', function(ServerRequestInterface $req, ResponseInterface $res) { 
    $data = $req->getParsedBody(); 
    $model = new \Apex\Models\User(ApexDB::getInstance()); 
    $jsonBuilder = ApexResponse::getBuilder('JSON', $res); 
    $control = new \Apex\Controllers\User($model, $jsonBuilder); 

    return $control->create($data); 
}); 

,然後你create方法也需要返回$response

public function create($data) { 
    if($this->model->save($data)) { 
     $this->response->build($data,201); 
    } else { 
     $this->response->build('error',400); 
    } 
    return $this->response; 
} 

它應該再工作。

但是,您可以從路線聲明直接使用控制器的方法,避免了封閉的必要性:

$app->post('/users', `Apex\Controllers\User::create`); 

然後,控制器的create方法是這樣的:

namespace Apex\Controllers; 

class User 
{ 
    public function create($request, $response) 
    { 
     $data = $request->getParsedBody(); 

     $model = new \Apex\Models\User(ApexDB::getInstance()); 
     $jsonBuilder = ApexResponse::getBuilder('JSON', $response); 

     if ($model->save($data)) { 
      $response = $jsonBuilder->build($data, 201); 
     } else { 
      $response = $jsonBuilder->build('error', 400); 
     } 
     return $response; 
    } 
} 

最後,考慮rka-content-type-renderer而不是JsonBuilder,雖然它可能比你展示的要多。


更新:

理想情況下,你會使用構造器注入到用戶模式注入到控制器。要做到這一點:

  1. 更新您的控制器:

    namespace Apex\Controllers; 
    
    use Apex\Models\User as UserModel; 
    
    class User 
    { 
        protected $userModel; 
    
        public function __construct(UserModel $userModel) 
        { 
         $this->userModel = $userModel; 
        } 
    
        public function create($request, $response) 
        { 
         $data = $request->getParsedBody(); 
    
         $jsonBuilder = ApexResponse::getBuilder('JSON', $response); 
    
         if ($this->userModel->save($data)) { 
          $response = $jsonBuilder->build($data, 201); 
         } else { 
          $response = $jsonBuilder->build('error', 400); 
         } 
         return $response; 
        } 
    } 
    
  2. 寫出疙瘩依賴注入容器廠:

    $container = $app->getContainer(); 
    $container['Apex\Controllers\User'] = function ($c) { 
        $userModel = new \Apex\Models\User(ApexDB::getInstance()); 
        return new \ApexController\User($userModel); 
    }; 
    
+0

哦,你可能還需要考慮在'201'響應中返回保存的用戶對象的'id'。在猜測中包含指向該用戶資源(/ users /:id)的端點的「位置」標題也是一個好主意。 –

+0

感謝您的詳細解答,是不是創建硬耦合來在控制器內創建模型實例?我以爲我可以使用構造函數注入?或服務容器?你認爲哪一個好? – Vignesh

+1

我會使用構造函數注入模型,是的。 –