Dinlenme API'leri - mobil belirli zorluklar


25

Mobil tarafta yeni bir iOS uygulaması projesi üzerinde çalışıyorum. Bazı mimari değişiklikler yaşanıyor ve geliştirdiğimiz uygulama tarafından ve ayrıca web sitesi gibi diğer müşteriler tarafından kullanılacak özel bir özel API'ye güvenmek zorunda kalacağız.

Tasarlanan API, HTTP fiilleriyle eşlenen kaynak merkezli URI ve CRUD işlemlerinin Dinlenme stilini takip eder. gibi şeyler:

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

Sorun, bu tarzın genellikle mobil istemcinin, tek bir uygulama ekranı yüklemek veya tek bir kullanıcı UI eylemini yönetmek için birçok istek yapma ihtiyacına yol açmasıdır. Bu, uygulamanın gereken her şeyi alana kadar 8 saniye boyunca yükleme modunda olmasına neden olur. Yavaş ve tepkisiz bir uygulama.

Mobil müşterilerin bağlantı söz konusu olduğunda ciddi kısıtlamaları vardır ve bu nedenle ideal olarak bu tür bir kurala uymalıyız:

1 ekran == 1 API çağrısı

1 kaydet == 1 API çağrısı.

Bunun sizi REST tasarım ilkeleri ile çarpışma rotasına sokması için birçok durum var, örneğin:

  • Diyelim ki uygulamanız bir gündür çevrimdışıydı ve arka uç veritabanlarının dört tablosu ile senkronize etmeniz ve www.example.com/sync_everything?since=2015-07-24
  • Diyelim ki kullanıcının nesnelerinin çoğunu düzenleyebileceği bir ekran var, örneğin yapılacaklar listesindeki görevleri işaretleyerek. Tüm bu görev kayıtlarını düzenleme başına bir API çağrısı yerine tek bir toplu API çağrısında düzenlemenin bir yolu olmalıdır.
  • SİPARİŞ, SALESMEN ve PRODUCT db tablolarından gelen bilgileri karıştıran bir ekran olduğunu varsayalım, bu verileri üç yerine bir aramada almalıyım.

risk şu ki, orada en Restful API'sine sahip olabiliriz ve aynı zamanda orada en yararsız mobil uygulama da var.

Mesele şu ki, orada sadece yeni bir müteahhitim ve ihtiyacım olan bu noktaları anlamama yardımcı olan bir şey, saygın kaynaklardan gelen bazı makaleler veya buna benzer şeyler. Mobil müşterileri için REST stilinden ödün veren belli başlı oyuncular (örneğin: birleşik toplam API bitiş noktaları kullanarak).

Veya bu genel sorun için herhangi bir çözüm. Teşekkürler!


3
Sorunuz, "Bir API, REST stilini koruyarak, benzer veya benzer türdeki gömülü nesnelerin koleksiyonlarını nasıl sunabilir?" Gibi olabilir. Sorunuzu anlıyor muyum?
joshp

Genel cevabın her REST çağrısının çeşitli isteğe bağlı parametreler alması gerektiğine inanıyorum, böylece esnek ama yine de sezgisel olabilir. Senkronizasyon durumu her zaman zor olacak, ancak normal sayfalar için normalde aynı türden birkaç çağrıya bakıyorsunuz , yani tüm GET'ler, değil mi?
Ixrec

1
Bence , sorun paralel isteklerin olmaması durumunda API’nizi uyarlamanın yanlış bir çözüm olduğunu düşünüyorum - 8 küçük istek, birbirlerini beklemek zorunda olmadıklarında, büyük bir istekten daha kötü değildir. HTTP / 2'ye geçebilir misiniz? Veya en azından HTTP / 1.1 boru hattını mı kullanıyorsunuz?
08:

Ayrıca bakınız: REST web servislerinde toplu işlemleri gerçekleştirme kalıpları? . Anahtar, ne tür komutların (ve hangi koşulların altında) çatışmalar olmadan bir araya getirilebileceğini tanımlamak ve ardından toplu siparişin bir JSON temsilini oluşturmak ve ardından göndermek. Önbelleğe alınabilirliği olan REST'in ana çekiciliğini kaybeder, ancak önbelleğe alınma her türlü uygulama için her zaman önemli değildir. Toplu bağımlılık varsa toplu iş / eşzamanlılığın geçerli olmadığını unutmayın.
rwong

Aracı aracın, bir dizide birden fazla işlemi gerçekleştirmesi gereken durumla ilgili olarak, önceki işlemlerin her birine önemsiz olmayan mantıksal bağımlılıklar olan bir benzetme, bir aracı içinde bu aracıda yürütülen, "saklı yordam" gibi bir şeydir. Alt kısımda, aracının tek bir "saklı yordam" çağrısını gerektiği kadar RESTful isteğine dönüştürmesine izin verilir, ancak bu aracı aracın bir uygulama detayıdır.
rwong

Yanıtlar:


27

Tasarlanan API, HTTP fiilleriyle eşlenen kaynak merkezli URI ve CRUD işlemlerinin Dinlenme stilini takip eder.

Bu senin problemin işte burada.

Kaynaklarınızı veritabanınızdaki modellerle (sanırım) sınırlandırdınız. Bu nedenle, tüm bu kaynakları yüklemek zaman alır çünkü sunucunuzun veritabanında temsili olmayan bir kaynak kavramı yoktur.

Örneğin olabilir

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

kütüphaneme ulaşmak için hepsinin yüklenmesi gerekiyor

Bu RESTful tasarımıyla ilgili bir sorun değil, bu gerçek bir REST karşıtı model. REST'te kaynaklarımızın, veritabanı modelleri de dahil olmak üzere sisteminizde başka bir şeyle birebir eşleşmesi gerektiğini söyleyen hiçbir şey yoktur.

Çözüm, yüklemek istediklerinizle daha iyi eşleşen daha fazla kaynak oluşturmaktır. Her zaman bir araya gelen 5 kaynağınız varsa, bu 5 kaynağın bilgisini içeren yeni bir kaynak oluşturun.

Sahip olman gereken bu gibi bir şey

www.example.com/users/334/my_library

bu kullanıcı için tüm kitapları yükler. "my_library" veritabanınızdaki bir model değil, bir kaynak. Sunucu, veritabanındaki modellere dayanarak oluşturur ancak bire bir eşleme yoktur ve sunucu, DB modelinizi değiştirmeden bu kaynağı oluşturma esnekliğine sahiptir.

Ayrıca olabilir

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

bunların hiçbirinin veritabanında veya etki alanı alanında model olarak bulunması gerekmez.

Rails gibi çerçeveler insanlara kaynakları birebir bir şekilde, 1'i 1'e tekrar veritabanı dizileriyle eşleştiren etki alanı alanındaki modellere eşlemelerini öğrettikleri için bunun yanlış bir şey olduğu konusunda yaygın bir yanlış kanı vardır. Bu gerekli değildir ve tavsiye edilmez.

Kaynaklar çok sayıda, ucuz ve hafif olmalıdır . Onları oluşturmak kolay olmalı ve etki alanı modelinizden soyutlanmaları gerekir. Yeni bir tanesine ihtiyacın olursa, sadece yeni bir tanesini yaratırsın. Bunu yapmakta zorluk çekiyorsanız, bu sizin hatalarınız REST'te bir hata değildir.

Şimdi elbette bununla ilgili en büyük uyarı, çerçevenin bunu yapmana izin verip vermeyeceği. “Zamandan tasarruf etmek” için 1'e 1'i eşlemek için kursa gitmiş olan Rails ve Django gibi çerçeveler bunu zorlaştırır. Ancak bu, RESTful tasarımında değil çerçevelerdeki bir kusurdur.

İşte Jim Webber bunun daha detaylı olduğunu tartışıyor (Rails'de birkaç kazı dahil!)

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


Bu çok ilginç ve buna tamamen katılıyorum ama ne yazık ki, API'yi yapan ben değilim ve varsa etkilemek için çok az yolum var. Birçok insan bu "anti-paterni" baştan sona kullanır (birçok nedenden ötürü, çerçeve kısıtlamaları birdir) ve sadece veritabanları hakkında net bir şekilde düşünmek için URI tanımını kullanır. API uç noktaları, DB'lerini görselleştirmenin başka bir yoludur ... Ayrıca, bazı durumlarda, nesnelerin gerçekten farklı olması nedeniyle tanımladığınız gibi bir kaynak oluşturmak zordur, çünkü bunların adlandırılması çok belirsiz terimlere yol açacaktır.
MikaelW

Verimlilik açısından konuya geri dönmek için, eğer bir mobil ekran çok yavaşsa (ve sadece bu gerçekleştiyse), bazı bileşik çağrılar yapılabileceğini, ancak API'yi saran bir bileşenin içinde oturacaklarını kabul ettiler. API'nin kendisinden ziyade), yalnızca mobil müşteriler tarafından kullanılacak ve çekirdek API'nin çekirdek API'sinin bir parçası olarak kabul edilmeyecektir.
MikaelW

@MikaelW, haklısın. Cormac'ın söylediği şey bile, ideal senaryodur, bazı zamanlar birçok başka sisteme (masaüstü, mobil, web, zamanlanmış işler, eski sistemler vb.) Katılmak isteyen bir API ile çalışıyorsunuz. Bu tür bir API'nin gerçekten esnek olması gerekir, mümkün olduğu kadar çok olasılığa katılmak için kaynaklar sağlar, ancak tek bir tüketicinin tüm spesifik performans gereksinimlerine katılamaz. Bu durumda çok fazla seçeneğiniz yok ...
Dherik
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.