API sisanya - tantangan khusus seluler

25

Saya sedang mengerjakan proyek aplikasi iOS baru, di sisi seluler. Beberapa perubahan arsitektur terjadi dan ternyata kita harus bergantung pada API pribadi yang dibuat khusus yang akan digunakan oleh aplikasi yang sedang kita bangun dan juga oleh klien lain seperti situs web.

API yang dirancang mengikuti gaya Istirahat dari operasi URI berbasis sumber daya dan CRUD yang dipetakan ke kata kerja HTTP. hal-hal seperti:

GET www.example.com/books
DELETE www.example.com/books/482094
POST www.example.com/users/6793

Masalahnya adalah bahwa gaya ini sering mengarah pada kebutuhan klien seluler untuk melakukan banyak permintaan untuk memuat layar aplikasi tunggal atau mengelola tindakan UI pengguna tunggal. Ini mengarah ke aplikasi berada dalam mode pemuatan selama 8 detik hingga memiliki semua yang dibutuhkan. Aplikasi lambat dan tidak responsif.

Klien seluler memiliki batasan serius dalam hal konektivitas dan idealnya, kita harus mengikuti aturan semacam itu:

1 layar == 1 panggilan API

1 simpan == 1 panggilan API.

Ada banyak situasi di mana ini menempatkan Anda pada jalur tabrakan dengan prinsip-prinsip desain REST, misalnya:

  • katakanlah aplikasi Anda telah offline selama sehari dan Anda perlu menyinkronkan dengan empat tabel dari database back-end dan Anda perlu panggilan seperti www.example.com/sync_everything?since=2015-07-24
  • katakanlah ada layar di mana pengguna dapat mengedit banyak objeknya, misalnya mencentang tugas dalam daftar todo-nya. harus ada cara untuk mengedit semua catatan tugas dalam satu panggilan API batch tunggal daripada satu panggilan API per edit.
  • katakanlah ada layar yang mencampur informasi dari tabel db ORDER, SALESMEN dan PRODUCT, saya harus mendapatkan data itu dalam satu panggilan, bukan tiga.

risikonya adalah kita mungkin berakhir dengan API yang paling tenang dan ada juga aplikasi seluler tidak responsif yang paling tidak berguna yang ada.

Masalahnya adalah saya hanya seorang kontraktor baru di sana dan yang saya butuhkan adalah sesuatu yang membantu saya membuat poin-poin itu, beberapa artikel dari sumber-sumber yang dihormati atau sesuatu seperti itu. Pemain besar yang berkompromi dengan gaya REST untuk klien seluler mereka (misalnya: dengan menggunakan titik akhir API agregat komposit).

Atau solusi apa pun untuk masalah umum ini. Terima kasih!

MikaelW
sumber
3
Kedengarannya seperti pertanyaan Anda mungkin, "Bagaimana API dapat mengirimkan koleksi objek dan objek yang disematkan dari jenis suka atau tidak suka sambil mempertahankan gaya REST?" Apakah saya mengerti pertanyaan Anda?
joshp
Saya percaya jawaban umum adalah bahwa setiap panggilan REST perlu mengambil berbagai parameter opsional sehingga bisa fleksibel namun masih relatif intuitif. Kasing sinkronisasi akan selalu rumit, tetapi untuk halaman biasa Anda biasanya melihat beberapa panggilan dengan tipe yang sama , yaitu semua GET, kan?
Ixrec
1
Saya pikir mengadaptasi API Anda adalah solusi yang salah ketika masalahnya adalah kurangnya permintaan paralel - 8 permintaan kecil tidak jauh lebih buruk daripada satu permintaan besar ketika mereka tidak harus menunggu satu sama lain. Bisakah Anda beralih ke HTTP / 2? Atau setidaknya menggunakan HTTP / 1.1 pipelining?
amon
Lihat juga: Pola untuk menangani operasi batch di layanan web REST? . Kuncinya adalah mengidentifikasi jenis perintah apa (dan di bawah prasyarat apa) yang dapat dikelompokkan bersama tanpa konflik, dan kemudian membuat representasi JSON dari urutan bets, dan kemudian mengirimkannya. Itu kehilangan daya tarik utama untuk REST yang merupakan cacheability tetapi cacheability tidak selalu relevan untuk semua jenis aplikasi. Perhatikan bahwa kumpulan / konkurensi tidak berlaku jika ada dependensi logis.
rwong
Analogi untuk situasi di mana tengkulak perlu melakukan beberapa operasi secara berurutan, dengan ketergantungan logis non-sepele pada setiap operasi sebelumnya, adalah sesuatu seperti "prosedur tersimpan", yang dieksekusi dalam tengkulak itu alih-alih di dalam database. Di bawahnya, tengkulak diizinkan untuk mengubah satu panggilan "prosedur tersimpan" menjadi permintaan sebanyak yang dibutuhkan, tetapi itu adalah detail implementasi tengkulak.
rwong

Jawaban:

27

API yang dirancang mengikuti gaya Istirahat dari operasi URI berbasis sumber daya dan CRUD yang dipetakan ke kata kerja HTTP.

Ini masalahmu di sini.

Anda telah membatasi sumber daya Anda untuk (saya mengasumsikan) model dalam database Anda. Karena itu butuh waktu lama untuk memuat semua sumber daya ini karena server Anda tidak memiliki konsep sumber daya yang tidak memiliki representasi dalam database.

Misalnya mungkin

www.example.com/books/482094
www.example.com/books/582045
www.example.com/books/427454
www.example.com/books/319343

itu semua harus dimuat untuk mendapatkan perpustakaan saya

Ini bukan masalah dengan desain RESTful, ini sebenarnya anti-pola REST. Sama sekali tidak ada dalam REST yang mengatakan sumber daya kami harus memiliki pemetaan satu lawan satu dengan apa pun di sistem Anda, termasuk model basis data.

Solusinya adalah menciptakan lebih banyak sumber daya yang lebih sesuai dengan apa yang ingin Anda muat. Jika Anda memiliki 5 sumber daya yang selalu berakhir bersama, buat sumber daya baru yang berisi info untuk 5 sumber daya tersebut.

Yang harus Anda miliki adalah sesuatu seperti ini

www.example.com/users/334/my_library

yang hanya memuat semua buku untuk pengguna itu. "my_library" bukan model dalam basis data Anda, tetapi merupakan sumber daya. Server membuatnya berdasarkan model dalam database tetapi tidak ada pemetaan 1-ke-1 dan server memiliki fleksibilitas untuk membuat sumber daya ini tanpa mengubah model DB Anda.

Anda mungkin juga memilikinya

www.example.com/users/334/favioured_books
www.example.com/users/334/books_ordered_last_week
www.example.com/users/334/wishlist

tidak ada yang harus ada sebagai model dalam database atau ruang domain Anda.

Ada kesalahpahaman yang tersebar luas bahwa ini adalah hal yang salah untuk dilakukan karena kerangka kerja seperti Rails mengajarkan orang untuk memetakan sumber daya dengan cara 1-ke-1 ke model dalam ruang domain yang memetakan lagi 1-ke-1 dengan baris basis data. Ini tidak perlu dan tidak direkomendasikan.

Sumber daya harus banyak, murah dan ringan . Seharusnya mudah membuatnya, dan harus diabstraksi dari model domain Anda. Jika Anda membutuhkan yang baru, Anda cukup membuat yang baru. Jika Anda memiliki masalah dalam melakukan itu, itu adalah kerangka kerja Anda bukan kesalahan dengan REST.

Sekarang peringatan besar dengan itu tentu saja adalah apakah kerangka kerja Anda memungkinkan Anda untuk melakukan ini. Kerangka kerja seperti Rails dan Django yang telah mengambil kursus untuk memetakan 1-ke-1 untuk "menghemat waktu Anda" membuatnya sulit untuk melakukan ini. Tapi itu cacat dengan kerangka, bukan dengan desain tenang.

Inilah Jim Webber yang membahas ini lebih detail (termasuk beberapa penggalian di Rails juga!)

https://yow.eventer.com/yow-2011-1004/domain-driven-design-for-restful-systems-by-jim-webber-1047

Cormac Mulhall
sumber
Ini sangat menarik dan saya sepenuhnya setuju dengan ini tetapi sayangnya, saya bukan orang yang melakukan API dan saya punya sedikit cara untuk mempengaruhinya, jika ada. Banyak orang akan menggunakan "anti-pola" di seluruh (karena berbagai alasan, keterbatasan kerangka menjadi satu) dan mereka hanya menggunakan definisi URI untuk berpikir jernih tentang database mereka. Titik akhir API hanyalah cara lain untuk memvisualisasikan DB mereka ... Juga, dalam beberapa kasus, membuat sumber daya seperti yang Anda gambarkan sulit karena fakta objek sangat berbeda, hanya memberi nama mereka akan mengarah ke istilah yang sangat kabur.
MikaelW
Untuk kembali ke masalah dari sudut efisiensi, mereka sepakat bahwa jika layar ponsel sangat lambat (dan hanya jika ini terjadi), akan ada beberapa panggilan komposit yang mungkin tetapi mereka akan duduk di komponen yang membungkus API ( daripada API itu sendiri), hanya akan digunakan oleh klien seluler dan tidak akan dianggap sebagai bagian dari API inti, domain inti.
MikaelW
@MikaelW, Anda benar. Bahkan apa yang dikatakan Cormac adalah skenario ideal, beberapa kali Anda bekerja dengan API yang perlu menghadiri banyak sistem lain (desktop, seluler, web, pekerjaan terjadwal, sistem lama, dll). Jenis API ini harus benar-benar fleksibel, menyediakan sumber daya untuk menghadiri sebanyak mungkin kemungkinan tetapi tidak dapat menghadiri semua kebutuhan kinerja spesifik dari satu konsumen. Dalam hal ini Anda tidak punya banyak pilihan ...
Dherik