2016-03-22 13 views
0

RESTful API için bu denetleyiciye sahibim Laravel Lumen'de göreceli olarak büyük miktarda parametre alan ve bunları sağladıkları zamana göre sorguların ve verilerin getirildiği yerlere ayrıştırıyorum. Örneğin,Büyük miktarda GET parametresini nasıl alabilirim ve onlara göre bir sorguyu filtreleyebilir miyim?

GET /nodes?region=California 
GET /nodes?ip=127.0.0.1 

Şu anda parametrelerin bir dizi (I Lumen'la ham olsun diziyi nasıl anlamaya ve olamazdı çünkü rahatsız edici olacaktır bina, yapıcı bunları alıyorum zaten çünkü ben Orada başka parametreler var) ve null değerlerini filtreleyerek (sorguda bulunmuyorsa değerleri null olarak ayarlıyorum).

Şimdi, her bir dizideki değerleri filtrelemeye gelince, bunu bir foreach dizisiyle yapıyorum. Bunu yapmak için anlayabileceğim en temiz yol, çok fazla kod gerektirmeden (denetleyicileri fazla şişmanlamak istemiyorum). Bunu yapmanın başka bir yolu var mı, belki de fonksiyonların/sınıfların ayrılmasıyla mı?

/** 
* 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;  
} 

cevap

2

Yani bir API bir kaynak listesini filtrelemeyi yapmak zorunda herhangi bir zaman, burada yapmam nasıl:

/** 
* 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; 
} 

Ve kontrolör kodu: Burada

benim yapıcı kodudur o.

Öncelikle, başlamadan önce, denetleyici yönteminizdeyken Request nesnesini almayla ilgili hızlı bir ipucu: Request $request işlevini all() işlevinize bir parametre olarak eklerseniz, $ request değişkenine erişiminiz olacaktır. orada, kurucununkiyle aynı. Böylece tam imza public function all(Request $request) olacaktır. Denetleyici yöntemleri, diğer sınıf yapıcıların Laravel/Lumen'de aldıkları aynı sihirli bağımlılık enjeksiyonuna sahiptir. Alternatif olarak, işlevinizde, belirli bir sınıfın bir nesnesini vermek için her zaman app() işlevini isteyebilirsiniz. Istek nesnesi 'istek' için kapsayıcıya bağlı olduğundan, tam sınıf adı veya yalnızca 'istek' için istekte bulunabilirsiniz: $request = app('request');

Böylece istek neslimde bir kez, denetleyici yöntemimin içinde Her filtreden, her filtrenin ne kadar karmaşık olduğuna bağlı olarak, bir grup veya bire bir olarak gidin. Bazen filtreler karmaşıktır, bir dizide patlatılması gereken virgülle ayrılmış kimliklerin bir listesi gibi. Yine de basit bir süzgeç filtresiyse, listeyi bir diziye atma ve bunun üzerinden geçme eğilimindeyim.

İşte bazı fikirler gösteren bir örnek işlevi var: Sen benim, sonuçlarını sınırlandırmak için paginate fonksiyonunu kullanılan fark edeceksiniz

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 
    */ 
} 

. Kaynakları listeleyen bir API son noktasını oluştururken, başlığınıza (tercihim) veya sonuçların ilk, önceki, sonraki ve son sayfasına nasıl ulaşılacağına ilişkin yanıt gövdesi bilgilerini koymak isteyeceksiniz. Laravel'deki Sayfalama özelliği, links() yöntemini kullanarak bağlantıların çoğunu yapılandırabildiğinden bunu kolaylaştırır.

Maalesef, istekte hangi filtre parametrelerinin geçirildiğini size bildirmeniz gerekir; böylece, oluşturdukları bağlantılara eklediğinden emin olabilirsiniz. Aksi takdirde, filtreleriniz olmadan bağlantıları geri alacaksınız, bu da istemciyi çağrı için çok iyi yapmaz.

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 
    */ 
} 

Sayfalandırmayı belgeleri burada bulunabilir: bunlar sayfa bağlantıları üzerine eklenebilir böylece

Yani burada filtre parametrelerini kayıt daha tam bir örnek https://laravel.com/docs/5.2/pagination

nasıl sayfalandırma bağlama örneği için can öyle sonunda https://developer.github.com/v3/#pagination


: Dehşet yapılması, Github API belgelerine kontrol Yaptığınız şeyden çok uzak değil, kavramsal olarak. Buradaki avantaj, kodu, her başlatıldığında farklı bir yöntem çağrılacak olsa bile, yapıcınız her başlatılışında kurucunuzda çalışmak yerine, onu gereksinim duyulan yönteme taşımanızdır.

Bu yardımcı olur umarım!

+0

Teşekkürler dostum! Beni doğru yolda buldum. Cevaplandı olarak işaretleme. –

İlgili konular