Katakanlah saya ingin memiliki sumber daya RESTful untuk orang-orang, di mana klien dapat menetapkan ID.
Seseorang terlihat seperti ini: {"id": <UUID>, "name": "Jimmy"}
Sekarang, bagaimana cara klien menyimpan (atau "PUT") itu?
PUT /person/UUID {"id": <UUID>, "name": "Jimmy"}
- sekarang kita memiliki duplikasi buruk yang harus kita verifikasi setiap saat: Apakah ID di badan cocok dengan yang ada di jalur?- Representasi asimetris:
PUT /person/UUID {"name": "Jimmy"}
GET /person/UUID
kembali{"id": <UUID>, "name": "Jimmy"}
- Tidak ada ID di badan - ID hanya di lokasi:
PUT /person/UUID {"name": "Jimmy"}
GET /person/UUID
kembali{"name": "Jimmy"}
- Tidak ada jenis
POST
tampaknya seperti ide yang baik karena ID yang dihasilkan oleh klien.
Apa pola umum dan cara mengatasinya? ID yang hanya berada di lokasi tampaknya merupakan cara yang paling benar secara dogmatis, tetapi ini juga mempersulit penerapan praktis.
id
disertai TO dengan id dan entitas serta konverter tambahan dan overhead yang terlalu besar untuk pemrogram.Jika ini adalah API publik, Anda harus bersikap konservatif saat membalas, tetapi terima dengan bebas.
Maksud saya, Anda harus mendukung 1 dan 2. Saya setuju bahwa 3 tidak masuk akal.
Cara untuk mendukung 1 dan 2 adalah dengan mendapatkan id dari url jika tidak ada yang disediakan di badan permintaan, dan jika ada di badan permintaan, maka validasikan bahwa itu cocok dengan id di url. Jika keduanya tidak cocok, kembalikan respons 400 Permintaan Buruk.
Saat mengembalikan resource person, bersikaplah konservatif dan selalu sertakan id di json, meskipun itu opsional di put.
sumber
Satu solusi untuk masalah ini melibatkan konsep yang agak membingungkan dari "Hypertext As The Engine Of Application State," atau "HATEOAS." Ini berarti bahwa respons REST berisi sumber daya atau tindakan yang tersedia untuk dilakukan sebagai hyperlink. Dengan menggunakan metode ini, yang merupakan bagian dari konsep asli REST, pengidentifikasi / ID unik dari sumber daya itu sendiri adalah hyperlink. Misalnya, Anda dapat memiliki sesuatu seperti:
Kemudian, jika Anda ingin mengupdate resource tersebut, Anda dapat melakukan (pseudocode):
Satu keuntungan dari ini adalah bahwa klien tidak harus memiliki ide tentang representasi internal server dari ID Pengguna. ID dapat berubah, dan bahkan URL itu sendiri dapat berubah, selama klien memiliki cara untuk menemukannya. Misalnya, saat mendapatkan sekumpulan orang, Anda bisa membalas seperti ini:
(Anda dapat, tentu saja, juga mengembalikan objek orang penuh untuk setiap orang, tergantung pada kebutuhan aplikasi).
Dengan metode ini, Anda lebih memikirkan objek Anda dalam hal sumber daya dan lokasi, dan lebih sedikit dalam hal ID. Representasi internal pengenal unik dengan demikian dipisahkan dari logika klien Anda. Ini adalah dorongan asli di balik REST: untuk membuat arsitektur klien-server yang lebih longgar digabungkan daripada sistem RPC yang ada sebelumnya, dengan menggunakan fitur HTTP. Untuk informasi lebih lanjut tentang HATEOAS, lihat artikel Wikipedia serta artikel pendek ini .
sumber
Dalam menyisipkan Anda tidak perlu menambahkan id di URL. Dengan cara ini jika Anda mengirim ID dalam PUT Anda dapat diartikan sebagai UPDATE untuk mengubah kunci utama.
MEMASUKKAN:
MEMPERBARUI
The JSON API menggunakan standar ini dan memecahkan beberapa masalah kembali objek dimasukkan atau diperbarui dengan link ke objek baru. Beberapa pembaruan atau sisipan mungkin menyertakan beberapa logika bisnis yang akan mengubah bidang tambahan
Anda juga akan melihat bahwa Anda dapat menghindari get setelah penyisipan dan pembaruan.
sumber
Ini telah ditanyakan sebelumnya - pembahasannya menarik untuk dilihat:
Haruskah respons RESTful GET mengembalikan ID sumber daya?
Ini adalah salah satu pertanyaan di mana mudah untuk terjebak dalam perdebatan tentang apa yang "tenang" dan apa yang tidak .
Untuk apa nilainya, saya mencoba untuk berpikir dalam hal sumber daya yang konsisten dan tidak mengubah desainnya di antara metode. Namun, IMHO, hal terpenting dari perspektif kegunaan adalah Anda konsisten di seluruh API!
sumber
Meskipun boleh saja memiliki representasi yang berbeda untuk operasi yang berbeda, rekomendasi umum untuk PUT adalah memuat muatan SELURUH . Itu artinya
id
harus ada juga. Jika tidak, Anda harus menggunakan PATCH.Karena itu, saya pikir PUT sebagian besar harus digunakan untuk pembaruan dan
id
harus selalu diteruskan di URL juga. Akibatnya, menggunakan PUT untuk memperbarui pengenal sumber daya adalah ide yang buruk. Itu membuat kita dalam situasi yang tidak diinginkan ketikaid
di URL bisa berbeda dariid
di dalam tubuh.Jadi, bagaimana kita menyelesaikan konflik seperti itu? Kami pada dasarnya memiliki 2 opsi:
Warning
(X-API-Warn
dll).Sedekat itu saya bisa menjawab pertanyaan ini karena topiknya secara umum adalah masalah opini.
sumber
FYI saja, jawabannya di sini salah.
Lihat:
https://restfulapi.net/rest-api-design-tutorial-with-example/
https://restfulapi.net/rest-put-vs-post/
https://restfulapi.net/http-methods/#patch
TARUH
PATCH
Jadi Anda harus menggunakannya dengan cara ini:
Praktik RESTful menunjukkan bahwa tidak masalah apa yang Anda PUT di / {id} - konten record harus diperbarui ke yang disediakan oleh payload - tetapi GET / {id} harus tetap ditautkan ke resource yang sama.
Dengan kata lain, PUT / 3 dapat mengupdate ke payload id menjadi 4, tetapi GET / 3 harus tetap menautkan ke payload yang sama (dan mengembalikan yang dengan id disetel ke 4).
Jika Anda memutuskan bahwa API Anda memerlukan pengenal yang sama di URI dan payload, tugas Anda adalah memastikannya cocok, tetapi gunakan PATCH alih-alih PUT jika Anda mengecualikan id dalam payload yang seharusnya ada secara keseluruhan . Di sinilah jawaban yang diterima salah. PUT harus menggantikan seluruh sumber daya, di mana tambalan mungkin parsial.
sumber
transformation applied to the body
. Bahkan ada mekanisme untuk klien ituallows a user agent to know when the representation body it has in memory remains current
, yaitu: serverMUST NOT send ... an ETag or Last-Modified ... unless the request's representation was saved without any transformation
.Tidak ada yang buruk dalam menggunakan pendekatan yang berbeda. tetapi saya pikir cara terbaik adalah solusi dengan 2nd .
itu sebagian besar digunakan dengan cara ini bahkan kerangka entitas menggunakan teknik ini ketika entitas ditambahkan dalam dbContext kelas tanpa ID yang dihasilkan adalah ID yang dihasilkan oleh referensi di Entity Framework.
sumber
Saya melihat ini dari sudut pandang JSON-LD / Semantic Web karena itu cara yang baik untuk mencapai kesesuaian REST yang nyata seperti yang telah saya uraikan dalam slide ini . Melihat dari perspektif itu, tidak ada pertanyaan untuk memilih opsi (1.) karena ID (IRI) dari sumber daya Web harus selalu sama dengan URL yang dapat saya gunakan untuk mencari / mendereferensi sumber daya. Saya pikir verifikasi tidak terlalu sulit untuk diterapkan juga tidak intens secara komputasi; jadi saya tidak menganggap ini sebagai alasan yang valid untuk menggunakan opsi (2.). Saya pikir opsi (3.) sebenarnya bukan opsi karena POST (buat baru) memiliki semantik yang berbeda dari PUT (perbarui / ganti).
sumber
Anda mungkin perlu melihat jenis permintaan PATCH / PUT.
Permintaan PATCH digunakan untuk memperbarui sumber daya sebagian sedangkan dalam permintaan PUT, Anda harus mengirim seluruh sumber daya ke tempat yang ditimpa di server.
Sejauh menyangkut ID di url, saya pikir Anda harus selalu memilikinya karena ini adalah praktik standar untuk mengidentifikasi sumber daya. Bahkan API Stripe bekerja seperti itu.
Anda dapat menggunakan permintaan PATCH untuk memperbarui sumber daya di server dengan ID untuk mengidentifikasinya tetapi tidak memperbarui ID sebenarnya.
sumber