상대적으로 많은 양의 매개 변수를 가져와 쿼리를 구문 분석하고 제공 여부에 따라 데이터를 가져 오는 Laravel Lumen에서 빌드중인 RESTful API 용 컨트롤러가 있습니다. 예를 들면
GET /nodes?region=California
GET /nodes?ip=127.0.0.1
나는 현재 생성자에서 매개 변수 배열을 만들고 (루멘에서 원시 get 배열을 얻는 방법을 알 수 없었고 이미 다른 매개 변수가 있기 때문에 불편할 것이기 때문에) 필터링하고 있습니다. null 값 (쿼리에없는 경우 값을 null로 설정합니다).
이제 배열의 각 값을 필터링 할 때 foreach 배열을 사용합니다. 이것은 너무 많은 코드없이 할 수있는 가장 깨끗한 방법입니다 (컨트롤러를 너무 뚱뚱하게 만들고 싶지 않습니다.). 함수 / 클래스를 분리하여 깔끔하게 수행 할 수있는 다른 방법이 있습니까?
내 생성자 코드는 다음과 같습니다.
/**
* Get some values before using functions.
*
* @param Request $request Instance of request.
*/
public function __construct(Request $request)
{
$this->offset = (int) $request->input('offset', 0);
// TODO: I'm not sure how to implement this, code in question
$this->filters = [
'region' => $request->input('region', null),
'name' => $request->input('name', null),
'ip' => $request->input('ip', null)
];
$this->filters = array_filter($this->filters, function ($v) {
return !is_null($v);
});
// Set a sane SQL limit.
$this->limit = 5;
$this->request = $request;
}
그리고 컨트롤러 코드 :
/**
* List all nodes.
*
* @return [string] [JSON containing list of nodes, if sorted.]
*/
public function all()
{
try {
// use filters provided
$data = Nodes::limit($this->limit)->offset($this->offset);
foreach ($this->filters as $filter => $value) {
$data->where($filter, $value);
}
$data = $data->get();
$response = $this->respond($data);
} catch (\Exception $e) {
$response = $this->respondServerError('Could not retrieve data from database.');
}
return $response;
}
따라서 API에서 리소스 목록 필터링을 수행해야 할 때마다 수행하는 방법은 다음과 같습니다.
하지만 먼저 시작하기 전에 컨트롤러 메서드에있을 때 Request 객체를 가져 오는 것에 관한 빠른 팁 : 함수에 Request $request
대한 매개 변수로 추가 all()
하면 생성자와 동일한 $ request 변수에 액세스 할 수 있습니다. . 따라서 완전한 서명은 public function all(Request $request)
. 컨트롤러 메서드에는 다른 클래스 생성자가 Laravel / Lumen에서 얻는 것과 동일한 매직 종속성 주입이 있습니다. 또는 함수에서 항상 app()
특정 클래스의 객체를 제공 하도록 함수에 요청할 수 있습니다 . Request 객체는 Container에서 'request'에만 바인딩되어 있으므로 전체 클래스 이름 또는 'request'만 요청할 수 있습니다.$request = app('request');
따라서 요청 객체가 있으면 컨트롤러 메서드 내에서 각 필터가 얼마나 복잡한 지에 따라 그룹으로 또는 하나씩 각 필터를 살펴보고 싶습니다. 때로는 필터가 배열로 분해되어야하는 쉼표로 구분 된 ID 목록처럼 복잡합니다. 그래도 단순한 문자열 필터라면 목록을 배열에 넣고 실행하는 경향이 있습니다.
다음은 몇 가지 아이디어를 설명하는 예제 함수입니다.
public function getIndex(Request $request)
{
//Create a User object to append WHERE clauses onto
$user = app('App\Models\User');
//Run through our simple text fields
foreach(['first_name', 'last_name', 'region', 'ip'] as $field) {
if ($request->has($field)) {
$user->where($field, $request->input($field));
}
}
//This field uses a LIKE match, handle it separately
if ($request->has('email')) {
$user->where('email', LIKE, '%' . $request->input('email') . '%');
}
//This field is a list of IDs
if ($request->has('id')) {
$ids = explode(',', $request->input('id'));
$user->whereIn('id', $ids);
}
//Use pagination
$users = $user->paginate(25);
/**
* Continue with the rest of response formatting below here
*/
}
결과를 제한하기 위해 페이지 매김 기능을 사용했음을 알 수 있습니다. 리소스를 나열하는 API 엔드 포인트를 빌드 할 때 첫 번째, 이전, 다음 및 마지막 결과 페이지를 가져 오는 방법에 대한 헤더 (내 기본 설정) 또는 응답 본문 정보를 입력 할 수 있습니다. Laravel의 Pagination 기능은 links()
메서드를 사용하여 대부분의 링크를 구성 할 수 있기 때문에이를 쉽게 만듭니다 .
안타깝게도 요청에서 전달 된 필터 매개 변수를 알려야 생성 된 링크에 추가 할 수 있습니다. 그렇지 않으면 필터없이 링크를 다시 얻을 수 있으므로 클라이언트가 페이징에 그다지 좋지 않습니다.
따라서 여기에 페이지 매김 링크에 추가 할 수 있도록 필터 매개 변수를 기록하는 더 완전한 예가 있습니다.
public function getIndex(Request $request)
{
//Create a User object to append WHERE clauses onto
$user = app('App\Models\User');
//List of filters we found to append to links later
$appends = [];
//Run through our simple text fields
foreach(['first_name', 'last_name', 'region', 'ip'] as $field) {
if ($request->has($field)) {
$appends[$field] = $request->input($field);
$user->where($field, $request->input($field));
}
}
//This field uses a LIKE match, handle it separately
if ($request->has('email')) {
$appends['email'] = $request->input('email');
$user->where('email', LIKE, '%' . $request->input('email') . '%');
}
//This field is a list of IDs
if ($request->has('id')) {
$appends['id'] = $request->input('id');
$ids = explode(',', $request->input('id'));
$user->whereIn('id', $ids);
}
//Use pagination
$users = $user->paginate(25);
//Make sure we append our filter parameters onto the pagination object
$users->appends($appends);
//Now calling $users->links() will return the correct links with the right filter info
/**
* Continue with the rest of response formatting below here
*/
}
페이지 매김 문서는 https://laravel.com/docs/5.2/pagination 에서 찾을 수 있습니다.
페이지 매김 링크가 어떻게 훌륭하게 수행되는지에 대한 예는 Github의 API 문서를 확인하십시오 : https://developer.github.com/v3/#pagination
결국 그것은 당신이하던 일과 개념적으로 그리 멀지 않습니다. 여기서 장점은 다른 메서드가 호출 되더라도 컨트롤러가 초기화 될 때마다 생성자에서 실행되는 대신 코드를 필요한 메서드로 이동한다는 것입니다.
도움이 되었기를 바랍니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다