Kepemilikan sumber daya di REST API

Dalam skenario berikut:

  • Pengguna dapat membuat Game.
  • Pengguna yang membuat game disebut Pemilik.
  • Game memiliki id uniknya sendiri secara global.
  • Pengguna lainnya dapat bergabung dengan Game yang bukan milik mereka, ini disebut Pemain.

Seseorang akan mengirimkan permintaan ke /game/{id} untuk mendapatkan data Game, yang harus sama untuk setiap klien, seperti:

{
   name: 'My Game',
   sport: 'Football'
   ...
}

Katakanlah kita harus menampilkan link "Pengaturan" untuk pemilik Game di Layar Game Utama. Tautan "Pengaturan" ini tidak dapat ditampilkan untuk Pemain reguler.

Baik Pemain maupun Pemilik dapat melihat Layar Utama Permainan.

Bagaimana cara memverifikasi kepemilikan sumber daya ini untuk menampilkan komponen yang berbeda kepada pengguna?

  • Saya pikir menambahkan ownerId ke respons akan menjadi tanggung jawab karena seseorang dapat mengubah nilai di sisi klien, bukan?
  • Selain itu, menambahkan bidang isOwner akan membuat respons tidak dapat di-cache.

person Felipe Francisco    schedule 08.06.2017    source sumber


Jawaban (3)


Jawabannya di sini mungkin terletak pada struktur tipe HATEOAS. Sumber daya Anda harus berisi daftar tautan yang dapat dinavigasi ke informasi/anak/daftar lain, dll. Jika 'pengaturan' adalah opsi bagi pengguna yang meminta, maka tautan ke pengaturan harus dikembalikan sebagai bagian dari objek, jika tidak, tidak ada tautan seperti itu akan ada.

Caching: Ini memang menimbulkan masalah, tapi bisa dipecahkan.

person Software Engineer    schedule 08.06.2017
comment
Dalam hal ini, bagaimana hal ini dapat diselesaikan dari sudut pandang caching? Responsnya menjadi berbasis pengguna dengan pendekatan ini. - person Felipe Francisco; 09.06.2017
comment
Masalah seperti yang dinyatakan tidak benar-benar dapat disimpan dalam cache -- Anda mendapatkan keluaran yang berbeda tergantung pada pengguna, itulah sebabnya kami biasanya tidak menyimpan data dalam cache. Anda harus membaginya menjadi dua permintaan, satu untuk objek dan satu lagi untuk metadatanya (yang mencakup referensi ke pengaturan). Dto awal dapat di-cache tetapi data spesifik pengguna tidak bisa. - person Software Engineer; 09.06.2017

Mari kita bicara tentang aplikasi server dan aplikasi klien. Aplikasi klien berisi Layar Game Utama dan akan menampilkan atau menyembunyikan beberapa panel bergantung pada sesuatu.

Aplikasi server harus menyediakan sesuatu ini. Karena aplikasi servernya adalah REST, maka aplikasi tersebut harus menyediakan bantuan. Apa jenis sumber dayanya dan di mana seharusnya berada?

GET /games/{gameId}/users/{userId}/something
GET /users/{userId}/games/{gameId}/something

Anda dapat menyebut sesuatu ini sebagai hak atau izin pengguna. Apakah ini sumber daya terpisah? Mungkin tidak. Jadi Anda bisa menerapkan metode tersebut

GET /games/{gameId}/users/{userId}

Metode ini akan mengembalikan profil pengguna dan izin terkait untuk game dengan id {gameId} seperti di sini:

{
    givenNames: 'Miguel de Cervantes',
    familyName: 'Saavedra',
    totalScore: 10342,

    permissions: {
        canClose: false,
        canSetup: false,
        . . .
    }
}

Dan tentu saja aplikasi server harus memeriksa izin untuk setiap permintaan klien.

person Mark Shevchenko    schedule 08.06.2017
comment
Terima kasih, ini pertama kalinya saya melihat pendekatan semacam ini, jadi saya punya beberapa pertanyaan tentang implikasi mengikuti jenis penanganan izin ini di seluruh aplikasi: Data profil pengguna saat ini dapat diambil dengan meminta titik akhir /users/{id}. Apakah boleh juga menyertakan data terkait pengguna di titik akhir yang disarankan ini (/games/{gameId}/users/{userId})? - person Felipe Francisco; 09.06.2017
comment
Dalam hal ini, berarti harus dibuat satu permintaan lagi untuk mendapatkan izin pengguna, bukankah ini akan menurunkan kinerja aplikasi? Dan karena node permissions akan menjadi standar di seluruh aplikasi, apa cara terbaik untuk mendokumentasikan berbagai jenis kunci izin (canClose, canSetup...) dalam dokumentasi? - person Felipe Francisco; 09.06.2017
comment
Pada pertanyaan pertama. Ya, tidak apa-apa. Terkadang subsumber daya dapat diakses melalui jalur yang berbeda, terutama ketika terdapat hubungan banyak ke banyak. Anda memiliki permainan, Anda memiliki pengguna, dan Anda memiliki semua permainan dari pengguna tertentu. - person Mark Shevchenko; 09.06.2017
comment
Pada pertanyaan kedua. Aturan umumnya adalah meneruskan data sebanyak mungkin dalam satu waktu (pola Remote Façade). Permissions adalah koleksi sederhana yang tidak besar sehingga Anda cukup memasukkannya ke dalam objek pengguna. Di JSON API Anda dapat menggunakan parameter kueri include untuk meneruskan kolom opsional yang diinginkan. - person Mark Shevchenko; 09.06.2017

Saya pikir pertama-tama Anda harus menyelesaikan masalah konsep yang terkait dengan tanggung jawab sumber daya, karena sumber daya yang mengembalikan informasi permainan, tidak boleh mengembalikan informasi keamanan seperti "melihat atau tidak melihat tombol".

Jadi, saya akan membuat sumber daya khusus untuk mengembalikan informasi keamanan seperti ini. Dalam sumber keamanan khusus ini, untuk kasus yang disebutkan di atas, saya tidak akan meneruskan parameter apa pun melalui URL dan melalui hash otentikasi saya akan mendapatkan id pengguna untuk memverifikasi apakah dia adalah pemilik game yang mengembalikan respons sederhana seperti benar atau salah untuk mengetahui jika pengguna tersebut dapat melihat tombol itu.

Jelas, sumber daya tersebut dapat menjawab banyak informasi keamanan tentang layar dan tombol lainnya.

Sumber daya seperti:

GET /security/buttons/{buttonId}

Dan di masa depan:

GET /security/screens/{screenId}
GET /security/functionalities/{functionalityId}
GET /security/actions/{actionId}
.
.
.
person Leo Ramos    schedule 09.06.2017
comment
Tombol tersebut hanyalah contoh abstrak karena saya tidak dapat membagikan skenario sebenarnya di sini. Tombol ini mewakili informasi dan tindakan yang secara eksklusif berkaitan dengan Pemilik Game. Adapun jawaban Anda, bukankah itu bertentangan dengan Konsep sumber daya dan juga RFC 3986? - person Felipe Francisco; 09.06.2017