php - having trouble with slimframework's Immutable responses -
i trying setup project api using slim framework version 3, don't know made psr-7 , marked response object immutable, don't see use in (imho. please explain me if wrong). things easier when slim 2. came slim after long time.
i have route post method, getting data , saving database , trying send 201 response code. examples , documentation showing how can change response code within index.php file itself, trying change response builder have tried use factory pattern provide different responses. problem response code stays 200 no matter function call response builder class. tried many forums , different ways of slim still couldn't able pull up. decided give on psr 7 router implementation , going implement own routing solution. remember not reinvent wheel again came here final try. below code.
the route definition
$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); });
the controller method (abstract setting up)
public function create($data) { if($this->model->save($data)) { $this->response->build($data,201); } else { $this->response->build('error',400); } }
the json builder
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; } }
can point me in right direction?
the psr-7 decision use immutable objects request , response documented in why value objects? section of meta document.
with slim 3, must return response
instance controller method.
$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); });
and create
method needs return $response
:
public function create($data) { if($this->model->save($data)) { $this->response->build($data,201); } else { $this->response->build('error',400); } return $this->response; }
it should work.
however, can use controller method directly route declaration , avoid need closure:
$app->post('/users', `apex\controllers\user::create`);
the controller's create
method this:
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; } }
finally, consider rka-content-type-renderer instead of jsonbuilder
, though maybe more you've shown.
update:
ideally you'd use constructor injection inject user model controller. this:
update controller:
namespace apex\controllers; use apex\models\user 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; } }
write factory pimple dependency injection container:
$container = $app->getcontainer(); $container['apex\controllers\user'] = function ($c) { $usermodel = new \apex\models\user(apexdb::getinstance()); return new \apexcontroller\user($usermodel); };
Comments
Post a Comment