Praktik terbaik untuk panggilan API REST dengan banyak parameter


11

Saya memiliki REST API dengan operasi GETs yang menerima daftar parameter (panjang) (misalnya 8 parameter). Tujuan operasi ini adalah untuk mencari dan memfilter elemen.

Manakah praktik terbaik untuk mengelola skenario ini ?:

(1) Menerima daftar parameter ?:

public ResultType Get(int p1, int p2, string p3...) { ... }

(2) Atau menerima objek yang merangkum parameter ini ?:

public class MyClass
{
    public int X { get; set; }
    public int Y { get; set; }
    public string Z { get; set; }
}

public ResultType Get(MyClass parameter) { ... }

Pikirkan dalam skenario eCommerce di mana Anda ingin mencari dan memfilter "produk" berdasarkan nama, deskripsi, kategori, merek, model, harga, dll ...


1
Posisi lebih rendah dari pengidentifikasi daripada nama yang tepat untuk suatu nilai.
SD

Mengapa Anda memiliki 8 parameter? Apa yang mereka lakukan? Apakah ada beberapa logika keputusan yang terlibat (dan apakah itu berantakan)? Bisakah Anda membagi api / metode menjadi beberapa metode yang mengambil 3 atau 4 parameter?
Filip Milovanović

1
8 parameter hanyalah sebuah contoh. Operasi Get saya adalah metode "pencarian". Pikirkan dalam skenario eCommerce di mana Anda ingin mencari dan memfilter "produk" berdasarkan nama, deskripsi, kategori, merek, model, harga, dll. Saya telah mengedit pertanyaan untuk menambahkan konteks
Jose Alonso Monge

Jawaban:


10

Saya memiliki REST API dengan operasi GETs yang menerima daftar> parameter (panjang). Manakah praktik terbaik untuk mengelola skenario ini?

AFAIK, tidak ada praktik terbaik yang mapan (maaf). Namun, seseorang dapat membuat beberapa rekomendasi:

  • Cobalah untuk menghindari penggunaanPOST (alih-alih GET) jika permintaan aman (yaitu efek samping gratis, khususnya tidak mengubah data). Jika parameternya sangat besar, Anda mungkin harus menggunakan POSTuntuk mengatasi batasan panjang, tetapi biasanya ini bukan masalah (sebagian besar perangkat lunak mendukung URL yang cukup panjang), dan permintaan yang aman harus digunakan GETuntuk memungkinkan optimisasi seperti caching dan prefetching.

  • Jika Anda menggunakan GET, Anda harus mengirim parameter Anda sebagai parameter URL 1) . Dalam situasi itu, solusi alami dan umum adalah dengan menggunakan daftar parameter , jadi itulah yang saya rekomendasikan. Ya, daftarnya akan panjang, tetapi REST API (mungkin) ditujukan untuk penggunaan terprogram, jadi saya tidak melihat masalah dengan ini. Pengguna API bebas untuk merangkum parameter dalam suatu objek di dalam kode mereka sendiri.

  • Secara teknis, Anda juga bisa memasukkan objek ke parameter URL (seperti JSON, XML atau apa pun), tetapi itu tidak biasa, jadi saya akan menghindarinya jika memungkinkan.

1) Sebenarnya, Anda dapat menggunakan tubuh dengan GETpermintaan, tetapi ini tidak biasa dan umumnya tidak disarankan; lihat misalnya HTTP DAPATKAN dengan badan permintaan .


Terakhir, seperti halnya metode dalam kode sumber yang memiliki daftar parameter panjang, Anda mungkin ingin mempertimbangkan apakah REST API membutuhkan refactoring. Sama seperti dalam kode sumber, daftar parameter yang panjang menunjukkan titik akhir API melakukan banyak hal berbeda. Apakah masuk akal untuk memisahkannya, atau memberikan pengaturan default? Tapi itu pertanyaan yang berbeda ...


Secara teknis Anda juga dapat mengirim tubuh dengan GET meskipun tidak biasa
Ewan

juga, apakah Anda yakin maksud Anda idempoten, saya akan mengatakan 'cacheable' GetTodaysDayName () mungkin dianggap idempoten, tetapi Anda tidak ingin melakukan cache
Ewan

Biarkan pertempuran GET vs POST dimulai !!!! :)
Ewan

@ Ewan: Untuk melakukan caching GetTodaysDayName: Dengan anggapan Anda membutuhkan nama hari ini sepuluh kali per detik, dan tidak peduli untuk menggunakan hari yang salah selama beberapa detik, Anda kemungkinan besar ingin menyimpannya. Namun, saya salah menggunakan "idempoten", yang ada dalam pikiran saya adalah "aman" (= tidak memodifikasi). Diedit.
sleske

1
@Ewan pertempuran konstruktif di mana "lawan" memperkaya respons satu sama lain lebih dari disambut. Terima kasih kepada Anda berdua untuk ikhtisar yang sangat komprehensif tentang semua opsi!
Christophe

3

Praktik terbaik adalah POST parameter sebagai objek.

Ini menghindari batas panjang URL dan masalah lain dengan string kueri. Jika Anda mengirim beberapa parameter dalam JSON maka objek adalah cara standar untuk melakukannya, jadi deserialising menjadi masuk akal.

Anda dapat menghindari membuat objek 'Permintaan' acak yang hanya digunakan di Pengontrol Anda dengan membatalkan deserialising ke objek dinamis jika Anda suka; meskipun casting ke tipe yang tepat setelahnya bisa sama berantakan.

Di masa lalu Anda akan dapat memiliki beberapa parameter dalam aksi controller Anda secara otomatis terikat ke bidang objek JSON yang masuk. Tapi ini tidak lagi berfungsi di luar kotak di .net core.

Meskipun ada ini, yang mungkin saya tergoda untuk mencoba

https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/application-model?view=aspnetcore-2.1#application-model-usage-in-webapicompatshim

Sunting: Hanya akan menambahkan beberapa poin tentang penggunaan GET

  • Caching: GET akan di-cache oleh klien yang mematuhi spesifikasi HTTP. Namun spek ini dirancang untuk membuat laman web memuat lebih cepat. Caching sangat membantu jika hasil API Anda memiliki persyaratan cache yang sama dengan halaman web, tetapi tidak membantu jika tidak. Anda dapat menambahkan caching Anda sendiri dari respons POST di klien jika diperlukan.

  • Panjang URL: Ini terutama masalah ketika Anda mengirim array. Jelas sebuah array dapat dengan mudah menjadi sangat panjang dan nama parameter string kueri akan diulang untuk setiap item. Namun, bahkan jika Anda hanya mengirim satu string, secara teknis string itu bisa sangat panjang.

  • Logging: Secara default banyak server web akan mencatat seluruh string kueri. Seringkali Anda tidak ingin data parameter berakhir di log teks biasa.

  • DAPATKAN dengan tubuh: Ini tampaknya menjadi jawaban yang sempurna, memuaskan purest REST sambil memungkinkan struktur data yang bagus, tetapi itu tidak biasa dan disukai, POST adalah cara standar untuk mengirim tubuh.


2
Saya pikir ini bukan praktik terbaik yang disetujui. Secara khusus, jika permintaan idempoten, itu adalah praktik terbaik untuk digunakan GETdan tidak PUT(untuk cacheability, antara lain). Dan batas panjang URL cukup besar saat ini, jadi belum tentu menjadi masalah.
sleske

@sleske Jika Anda berpikir GET lebih baik, Anda harus menulis jawaban tentang mengapa. String z dapat sepanjang 4Mb
Ewan

sebenarnya hanya googling dan panjang tali max json tampaknya tidak pasti
Ewan

Mengingat konteksnya, tidak perlu memiliki parameter permintaan tidak di log Anda - kecuali jika Anda tidak ingin melakukan analisis pada apa yang dicari orang di halaman Anda;) GETsangat masuk akal dari dua perspektif: a) analitik dan b) a pengguna dapat menyimpan kueri untuk nanti atau membagikan kueri.
Thomas Junk

@ThomasJunk konteks apa yang Anda rujuk? string disebut 'z', mungkin ada apa pun di dalamnya. apa denda GDPR $ 20 juta?
Ewan
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.