Saya sedang mendesain aplikasi web dan kemudian berhenti untuk memikirkan bagaimana api saya harus dirancang sebagai layanan web yang tenang. Untuk saat ini, sebagian besar URI saya bersifat generik dan mungkin berlaku untuk berbagai aplikasi web:
GET /logout // destroys session and redirects to /
GET /login // gets the webpage that has the login form
POST /login // authenticates credentials against database and either redirects home with a new session or redirects back to /login
GET /register // gets the webpage that has the registration form
POST /register // records the entered information into database as a new /user/xxx
GET /user/xxx // gets and renders current user data in a profile view
POST /user/xxx // updates new information about user
Saya merasa saya melakukan banyak kesalahan di sini setelah melihat-lihat SO dan Google.
Dimulai dengan /logout
, mungkin karena saya tidak benar-benar GET
apa-apa - mungkin lebih tepat untuk POST
meminta /logout
, menghancurkan sesi, dan kemudian GET
pengalihan. Dan haruskah /logout
istilah itu tetap ada?
Tentang /login
dan /register
. Saya dapat mengubah /register
ke /registration
tetapi itu tidak mengubah cara kerja layanan saya secara fundamental - jika ada masalah yang lebih dalam.
Saya perhatikan sekarang bahwa saya tidak pernah mengekspos /user
sumber daya. Mungkin itu bisa dimanfaatkan entah bagaimana. Misalnya, ambil pengguna myUser
:
foo.com/user/myUser
atau
foo.com/user
Pengguna akhir tidak memerlukan verbositas ekstra di URI. Namun, mana yang lebih menarik secara visual?
Saya memperhatikan beberapa pertanyaan lain di SO tentang bisnis REST ini, tetapi saya akan sangat menghargai beberapa panduan tentang apa yang telah saya paparkan di sini jika memungkinkan.
Terima kasih!
MEMPERBARUI:
Saya juga ingin beberapa pendapat tentang:
/user/1
vs.
/user/myUserName
sumber
Jawaban:
Satu hal yang menonjol khususnya sebagai tidak REST-ful: penggunaan permintaan GET untuk logout.
(dari http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods )
Untuk logout dan redirect, Anda bisa membuat postingan ke URI logout Anda memberikan respons 303 yang mengarahkan ke halaman setelah logout.
http://en.wikipedia.org/wiki/Post/Redirect/Get
http://en.wikipedia.org/wiki/HTTP_303
Edit untuk mengatasi masalah desain URL:
"Bagaimana cara mendesain sumber daya saya?" adalah pertanyaan penting bagi saya; "bagaimana cara mendesain URL saya?" adalah pertimbangan di dua bidang:
URL yang akan dilihat pengguna seharusnya tidak terlalu jelek dan bermakna jika memungkinkan; jika Anda ingin cookie dikirim dalam permintaan ke beberapa sumber daya tetapi tidak ke yang lain, Anda harus menyusun jalur dan jalur cookie Anda.
Jika
JRandomUser
ingin melihat profilnya sendiri dan Anda ingin URL-nya lebih cantik darifoo.com/user/JRandomUser
ataufoo.com/user/(JRandom's numeric user id here)
, Anda dapat membuat URL terpisah hanya agar pengguna melihat informasinya sendiri:Saya akan mengklaim ketidaktahuan jauh lebih mudah daripada kebijaksanaan tentang hal ini, tetapi berikut adalah beberapa pertimbangan desain sumber daya:
sumber
GET foo.com/profile/
) apakah itu akan menjadi bagian dari, seperti yang disarankan momo, lapisan presentasi? Dengan kata lain, apa tepatnya yang harusGET
dikembalikan permintaan itu? Halaman web atau JSON?GET
,POST
,PUT
, danDELETE
sumber daya. Situs web hanyalah platform lain yang mengakses API. Dengan kata lain, desain URL situs web benar-benar berbeda dari desain RESTful API. Tolong beritahu saya jika saya masih salah haha.RESTful dapat digunakan sebagai pedoman untuk membuat URL, dan Anda dapat membuat sesi dan sumber daya pengguna :
GET /session/new
mendapatkan halaman web yang memiliki formulir loginPOST /session
mengautentikasi kredensial terhadap databaseDELETE /session
hancurkan sesi dan alihkan ke /GET /users/new
mendapatkan halaman web yang memiliki formulir pendaftaranPOST /users
mencatat informasi yang dimasukkan ke dalam database sebagai / pengguna / xxx baruGET /users/xxx
// mendapatkan dan merender data pengguna saat ini dalam tampilan profilPOST /users/xxx
// memperbarui informasi baru tentang penggunaIni bisa jamak atau tunggal (saya tidak yakin mana yang benar). Saya biasanya menggunakan
/users
halaman indeks pengguna (seperti yang diharapkan), dan/sessions
untuk melihat siapa yang masuk (seperti yang diharapkan).Menggunakan nama di URL alih-alih angka (
/users/43
vs./users/joe
) biasanya didorong oleh keinginan untuk lebih bersahabat dengan pengguna atau mesin pencari, bukan persyaratan teknis. Keduanya baik-baik saja, tetapi saya sarankan Anda konsisten.Saya pikir jika Anda menggunakan register / login / logout atau
sign(in|up|out)
, itu tidak berfungsi dengan baik dengan terminologi yang tenang.sumber
/new
keGET /session/
non RESTful? Saya pernah mendengar bahwa kata kerja biasanya diserahkan kepada verba HTTP (GET
,POST
, dll).Sesi tidak tenang
Ya saya tahu. Ini dilakukan, biasanya dengan OAuth, tetapi sesi sebenarnya tidak TENANG. Anda tidak boleh memiliki sumber daya / login / logout terutama karena Anda tidak boleh memiliki sesi.
Jika Anda ingin melakukannya, buatlah tenang. Sumber daya adalah kata benda dan / login dan / logout bukan kata benda. Saya akan memilih / session. Ini membuat pembuatan dan penghapusan menjadi tindakan yang lebih alami.
POST vs. GET untuk sesi itu mudah. Jika Anda mengirim pengguna / kata sandi sebagai variabel, saya akan menggunakan POST karena saya tidak ingin kata sandi dikirim sebagai bagian dari URI. Ini akan muncul di log dan mungkin diekspos melalui kabel. Anda juga berisiko mengalami kegagalan perangkat lunak pada batasan GET args.
Saya biasanya menggunakan Basic Auth atau no Auth dengan layanan REST.
Membuat pengguna
Itu satu sumber daya, jadi Anda tidak perlu / mendaftar.
Jenis ID yang akan digunakan adalah pertanyaan yang sulit. Anda harus berpikir tentang menegakkan keunikan, tentang penggunaan kembali ID lama yang telah DIHAPUS. Misalnya, Anda tidak ingin menggunakan id tersebut sebagai kunci asing di backend jika id akan didaur ulang (jika memungkinkan). Anda dapat melakukan pencarian untuk konversi id eksternal / internal untuk mengurangi persyaratan backend.
sumber
Saya hanya akan berbicara dari pengalaman saya mengintegrasikan berbagai Layanan Web REST untuk klien saya, apakah itu digunakan untuk aplikasi seluler atau untuk komunikasi server ke server serta membangun REST API untuk orang lain. Berikut adalah beberapa observasi yang telah saya kumpulkan dari REST API orang lain serta yang kami buat sendiri:
Karena REST dirancang sebagai layanan, fungsi seperti login dan logout biasanya mengembalikan hasil keberhasilan / kegagalan (biasanya dalam format data JSON atau XML) yang kemudian akan ditafsirkan oleh konsumen. Interpretasi tersebut dapat mencakup pengalihan ke halaman web yang sesuai seperti yang Anda sebutkan
Itulah beberapa poin dari apa yang telah saya tangani. Saya harap ini bisa memberikan beberapa wawasan untuk Anda.
Sekarang sejauh implementasi REST Anda, ini adalah implementasi khas yang saya temui:
Jalankan logout di backend dan kembalikan JSON untuk menunjukkan keberhasilan / kegagalan operasi
Kirimkan kredensial ke backend. Kembalikan kesuksesan / kegagalan. Jika berhasil, biasanya itu juga akan mengembalikan token sesi serta informasi profil.
Kirimkan pendaftaran ke backend. Kembalikan kesuksesan / kegagalan. Jika berhasil, biasanya diperlakukan sama dengan login yang berhasil atau Anda dapat memilih untuk membuat pendaftaran sebagai layanan yang berbeda
Dapatkan profil pengguna dan kembalikan format data JSON untuk profil pengguna
Posting informasi profil yang diperbarui sebagai format JSON dan perbarui informasi di backend. Kembalikan berhasil / gagal ke pemanggil
sumber
Saya percaya ini adalah pendekatan yang tenang untuk otentikasi. Untuk Login yang Anda gunakan
HttpPut
. Metode HTTP ini dapat digunakan untuk pembuatan jika kunci disediakan, dan panggilan berulang tidak berdaya. Untuk LogOff, Anda menentukan jalur yang sama di bawahHttpDelete
metode. Tidak ada kata kerja yang digunakan. Pluralisasi koleksi yang tepat. Metode HTTP mendukung tujuan tersebut.Jika diinginkan, Anda dapat mengganti arus dengan aktif.
sumber
Saya akan merekomendasikan menggunakan URL akun pengguna yang mirip dengan twitter di mana URL akun pengguna akan menjadi seperti
foo.com/myUserName
seperti Anda bisa masuk ke akun twitter saya dengan URL https://twitter.com/joelbylerSaya tidak setuju tentang logout yang membutuhkan POST. Sebagai bagian dari API Anda, jika Anda akan mempertahankan sesi, maka id sesi dalam bentuk UUID mungkin merupakan sesuatu yang dapat digunakan untuk melacak pengguna dan mengonfirmasi bahwa tindakan yang diambil telah diotorisasi. Kemudian, bahkan GET dapat meneruskan id sesi ke sumber daya.
Singkatnya saya akan merekomendasikan agar Anda tetap sederhana, URL harus pendek dan mudah diingat.
sumber