Apakah ada masalah dengan penerapan metode HTTP khusus?

34

Kami memiliki URL dalam format berikut

/ instance / {instanceType} / {instanceId}

Anda dapat menyebutnya dengan metode HTTP standar: POST, GET, DELETE, PUT. Namun, ada beberapa tindakan lain yang kami ambil seperti "Simpan sebagai konsep" atau "Kurator"

Kami pikir kami bisa menggunakan metode HTTP khusus seperti: DRAFT, VALIDATE, CURATE

Saya pikir ini dapat diterima karena standar mengatakan

"Seperangkat metode umum untuk HTTP / 1.1 didefinisikan di bawah ini. Meskipun set ini dapat diperluas, metode tambahan tidak dapat diasumsikan untuk berbagi semantik yang sama untuk klien dan server yang diperluas secara terpisah."

Dan alat-alat seperti WebDav membuat beberapa ekstensi mereka sendiri.

Apakah ada masalah yang dialami seseorang dengan metode khusus? Saya sedang memikirkan server proxy dan firewall tetapi ada bidang lain yang menjadi perhatian. Haruskah saya tetap di sisi aman dan hanya memiliki parameter URL seperti action = validate | curate | draft?

Juan Mendes
sumber
6
Seperti yang saya kutip dari RFC 1925 lagi - "Dalam desain protokol, kesempurnaan telah dicapai bukan ketika tidak ada yang tersisa untuk ditambahkan, tetapi ketika tidak ada yang tersisa untuk diambil." - jika berhasil, tidak ada alasan untuk menambahkan ke http.
4
Tidak ada yang salah, selama Anda menyadari bahwa Anda sekarang menggunakan protokol khusus dan bukan HTTP.
user16764
10
@ user16764 "Seperangkat metode umum untuk HTTP / 1.1 didefinisikan di bawah. Meskipun set ini dapat diperluas, metode tambahan tidak dapat diasumsikan untuk berbagi semantik yang sama untuk klien dan server yang diperluas secara terpisah." w3.org/Protocols/rfc2616/rfc2616-sec9.html Oleh karena itu diizinkan, dan itu masih HTTP
Juan Mendes
imho tidak ada yang menambah / menghapus dari HTTP karena definisi metode menyatakan bahwa menggunakan metode kustom sudah dapat diterima dalam lingkup HTTP / 1.1 tetapi tidak dapat diharapkan untuk berbagi semantik yang sama, jadi saya kira poin dari @MichaelT dan Juan Mendes dapat agak ditenangkan
Prof83

Jawaban:

42

Salah satu kendala yang mendasar dari HTTP dan yang fitur desain pusat REST adalah antarmuka seragam yang disediakan oleh (antara lain) satu set, tetap kecil metode yang berlaku universal untuk semua sumber daya. Kendala antarmuka yang seragam memiliki sejumlah kelebihan dan kekurangan. Saya mengutip dari Fielding secara bebas di sini.

Antarmuka yang seragam:

  • lebih sederhana.
  • memisahkan implementasi dari layanan yang mereka berikan.
  • memungkinkan arsitektur berlapis, termasuk hal-hal seperti penyeimbang beban HTTP (nginx) dan cache (pernis).

Di sisi lain, antarmuka yang seragam:

  • menurunkan efisiensi, karena informasi ditransfer dalam bentuk standar daripada yang khusus untuk kebutuhan aplikasi.

Pengorbanan "dirancang untuk kasus umum Web" dan telah memungkinkan ekosistem besar yang akan dibangun yang memberikan solusi untuk banyak masalah umum dalam arsitektur web. Mematuhi antarmuka yang seragam akan memungkinkan sistem Anda mengambil manfaat dari ekosistem ini sementara memecahnya akan membuatnya menjadi sulit. Anda mungkin ingin menggunakan load balancer seperti nginx tetapi sekarang Anda hanya bisa menggunakan load balancer yang mengerti DRAFT dan CURATE. Anda mungkin ingin menggunakan lapisan cache HTTP seperti Varnish tetapi sekarang Anda hanya dapat menggunakan lapisan cache HTTP yang memahami DRAFT dan CURATE. Anda mungkin ingin meminta bantuan seseorang untuk memecahkan masalah kegagalan server tetapi tidak ada orang lain yang tahu semantik untuk permintaan CURATE. Mungkin sulit untuk mengubah perpustakaan klien atau server pilihan Anda untuk memahami dan menerapkan metode baru dengan benar. Dan seterusnya.

Cara * yang benar untuk mewakili ini adalah sebagai transformasi negara pada sumber daya (atau sumber daya terkait). Anda tidak DRAFT pos, Anda mengubah draftkeadaannya trueatau Anda membuat draftsumber daya yang berisi perubahan dan tautan ke versi konsep sebelumnya. Anda tidak MENCIPTAKAN sebuah posting, Anda mengubah statusnya curatedmenjadi trueatau membuat curationsumber daya yang menghubungkan postingan dengan pengguna yang membuat itu.

* Benar karena mengikuti prinsip arsitektur REST.

Rein Henrichs
sumber
Terima kasih atas komentar tentang load balancing, saya pasti akan melihatnya. Apakah Anda tahu sumber daya yang menyatakan apakah metode khusus dapat diterima atau tidak?
Juan Mendes
2
Saya tidak melihat keuntungan dari metode kustom kecuali mereka adalah bagian dari ekstensi yang didukung secara luas seperti WEBDAV (dan bahkan kemudian, tidak begitu banyak) jadi saya tidak pernah melihatnya. Saya hanya menyarankan Anda memperlakukan perubahan ini sebagai transformasi negara. Web berfungsi dengan baik dengan metode yang sudah kita miliki. Sebenarnya tidak ada alasan yang baik untuk menambahkan lebih banyak kecuali mereka masuk akal sebagai bagian dari antarmuka seragam (seperti PATCH).
Rein Henrichs
5
Saya melihat keuntungan dalam mendesain cara Anda ingin layanan HTTP Anda bekerja untuk diri Anda sendiri. namun "metode tambahan tidak dapat diasumsikan memiliki semantik yang sama" - Cukup adil, TETAPI masih merupakan bagian dari lingkup HTTP / 1.1, oleh karena itu firewall, proxy, load balancers dan sejenisnya harus memungkinkan untuk kemungkinan ini, jika mereka tidak t kemudian apakah mereka tidak mengimplementasikan HTTP / 1.1 dengan benar?
Prof83
Anda mungkin benar dari POV resty, namun, saya tidak dapat melihat mengapa kata kerja khusus harus menjadi masalah. Semua alat harus memperlakukannya seperti POST, yaitu, "sumber daya mungkin berubah dan hanya itu yang kita ketahui".
maaartinus
7

Saya lebih suka merancang ini sebagai sub-sumber daya, di mana Anda melakukan permintaan POST.

Anggap Anda memiliki sumber daya /instance/type/1, saya akan meminta perwakilan sumber daya tersebut menyampaikan beberapa tautan ke 'tindakan' yang dapat dilakukan pada sumber daya tersebut, seperti /instance/type/1/draftdan /instance/type/1/curate. Di JSON, ini bisa sesederhana:

{
    "some property":"the usual value",
    "state": "we can still inform the client about the current state",
    "draft": "http://server/instance/type/1/draft",
    "curate": "http://server/instance/type/1/curate"
}

Ini memungkinkan klien untuk menjadi sangat eksplisit tentang apa yang perlu terjadi, selama permintaan POST ke tautan yang disediakan oleh curateanggota. Sumber daya yang diposting di sana dapat mencakup argumen yang merinci acara yang akan, mungkin, menimbulkan transisi negara.

Pergi dengan pendekatan 'naif' untuk bergerak di antara negara-negara yang mungkin menggunakan sumber daya memiliki kelemahan karena tidak menangkap peristiwa apa yang menyebabkan transisi ini.

Transisi keadaan biasanya terjadi sebagai respons terhadap peristiwa tertentu, dan saya lebih suka menangkap peristiwa itu daripada membiarkan klien memutuskan bahwa ada sesuatu yang sekarang dalam 'keadaan' tertentu. Itu juga membuat validasi jauh lebih sulit. Plus, Anda tidak akan dapat menangkap 'argumen' apa pun kecuali Anda mendeskripsikannya di negara bagian itu sendiri. Dan kemudian semuanya menjadi menjengkelkan ketika beberapa kode mengubah kode-kode itu tanpa transisi keadaan sebenarnya, dan validasi diperlukan, dan semuanya dengan cepat menjadi berantakan.

Dave Van den Eynde
sumber
Jawaban yang bagus. Mampu memberikan argumen untuk transisi-negara & memiliki server merangkum dan mengelola ini, sejauh ini merupakan pendekatan terbaik.
Thomas W
Perusahaan saya saat ini di (VMware) melakukan ini. GET saat /vms/some-idmengembalikan tautan ke tindakan seperti POST /vms/some-id/restartdan kami menggunakannya untuk menentukan apakah tindakan harus diaktifkan atau dinonaktifkan. Saya memiliki hubungan cinta / benci dengan HATEOAS :)
Juan Mendes
Akan jauh lebih masuk akal jika tindakan yang diambil adalah kata kerja dari permintaan versus beberapa parameter kueri acak, segmen jalur sumber daya, atau properti tubuh.
Matthew Whited
Anda tidak dapat menautkan ke kata kerja.
Dave Van den Eynde
6

Saya pikir metode HTTP khusus adalah cara terbaik untuk menerapkan tindakan entitas. Menambahkan tindakan ke badan entitas (POST) tampaknya tidak benar, itu bukan bagian dari entitas Anda (walaupun hasilnya mungkin disimpan di dalamnya). Juga, menggunakan proksi metode HTTP khusus dapat menentukan tindakan mereka tanpa perlu mem-parsing badan entitas.

Ini seperti CRUD, Anda selalu ingin mengimplementasikannya, tetapi Anda juga memiliki serangkaian tindakan spesifik (per enitity). Saya benar-benar tidak melihat apa yang menjadi masalah dalam memperpanjangnya.

Juga @Rein Henrichs "Anda tidak DRAFT pos, Anda mengubah keadaan konsepnya menjadi benar atau Anda membuat sumber daya konsep" tampaknya salah bagi saya. Sebuah draftsproperti akan digunakan untuk terus-menerus menyimpan negara, bukan untuk membuat transformasi. Tindakan bahkan tidak selalu menghasilkan 'keadaan', atau disimpan di properti. Membuat entitas yang terpisah untuk setiap keadaan / transformasi tampaknya bahkan lebih kabur. Cobalah untuk mempertahankan referensi yang sama (URI) dengan enity.

Robert de W
sumber
1
Ini adalah poin yang adil meskipun tidak setuju secara luas, saya dapat melihat alasan di baliknya dan saya tidak setuju dengan downvote (terutama tanpa komentar dari pemilih). Mari kita ambil penanganan pengecualian PHP sebagai contoh, "Praktik Terbaik" tampaknya condong ke arah menggunakan jenis pengecualian khusus untuk menyarankan jenis pengecualian, bahkan mengabaikan pesan aktual seperti RuntimeException vs BadMethodCallException. Jadi mengapa begitu banyak yang menentang penggunaan DRAFT jika menggunakan metode kustom sudah dianggap bagian dari lingkup HTTP / 1.1? Dan load balancers dan proxy harus benar-benar menerima kemungkinan ini juga
Prof83