2015-03-01 33 views
25

Flask ve Python ile bir RESTful web hizmeti tasarlamaya başladım ve aynı projede birden çok API sürümünü nasıl destekleyeceğini merak ediyorum. Böyle URL'de istenen API sürümü koyarak düşünüyorum: Ben API 1.1 Versiyonu başka uç noktasını ekleyebilir ve v1 kadar her şeyi tutmak istiyorum Bir süre sonraŞişedeki çoklu API sürümlerini destekle

/myapp/v1/Users 

hangi değişmedi:

"Kullanıcılar" Uç Nokta v2 olarak
/myapp/v1.1/Users <= Same as in v1 
/myapp/v1.1/Books 

değiştirilir:

/myapp/v2/Users <= Changed in v2 
/myapp/v2/Books <= Same as in v1.1 

vb ...

En kolay yolu muhtemelen this soruya baktığımızda

böyle bir şey olurdu:

@app.route('/<version>/users') 
def users(version): 
    # do something 
    return jsonify(response) 

Ama bu her yeni API sürümü ile bakımı zordur alacak tahmin edebilirsiniz. Bu nedenle, Flask ile daha iyi (daha kolay bakım ve daha iyi yapılandırılmış) bir yol olup olmadığını merak ediyordum?

cevap

47

Başvuruda bulunduğunuz soru üzerinde kabul edilen yanıtın yazarıyım. Bence, /<version>/users yaklaşımının söylediğiniz kadar etkili olmadığını düşünüyorum. Üç veya dört farklı versiyonu yönetmeniz gerekiyorsa, spagetti koduyla sonuçlanacaksınız.

Orada önerdiğim nginx fikri daha iyi, ancak iki ayrı uygulamayı barındırmanız gereken dezavantaja sahip. O zaman, her bir API sürümü için bir plan kullanmak olan üçüncü bir alternatifi belirtmeyi özledim. Eğer ortak fonksiyonları uygulayan bir api/common.py var Burada

my_project 
+-- api/ 
    +-- v1/ 
     +-- __init__.py 
     +-- routes.py 
    +-- v1_1/ 
     +-- __init__.py 
     +-- routes.py 
    +-- v2/ 
     +-- __init__.py 
     +-- routes.py 
    +-- __init__.py 
    +-- common.py 

o API ihtiyacı tüm sürümleri: Örneğin, (büyük ölçüde netlik için basitleştirilmiş) Aşağıdaki uygulamanın yapısını düşünün. Örneğin, v1 ve v1.1 ile aynı olan /users rotanıza yanıt veren bir yardımcı fonksiyona sahip olabilirsiniz (rota olarak değil).

yolları tanımlamak her API sürümü için routes.py ve common.py fonksiyonlarına gerekli çağrı mantığı çoğaltarak önlemek için. Örneğin, v1 ve v1.1 routes.py sahip olabilir:

from api import common 

@api.route('/users') 
def get_users(): 
    return common.get_users() 

Not api.route. Burada api bir blueprint. Her bir API sürümünün bir plan olarak uygulanması, her şeyin doğru sürüm URL'lerle birleştirilmesine yardımcı olur.

from api.v1 import api as api_v1 
from api.v1_1 import api as api_v1_1 
from api.v2 import api as api_v2 

app.register_blueprint(api_v1, url_prefix='/v1') 
app.register_blueprint(api_v1_1, url_prefix='/v1.1') 
app.register_blueprint(api_v2, url_prefix='/v2') 

Bu yapı tüm API sürümleri ayrı tutar, ama onlar aynı uygulama tarafından sunulmaktadır çünkü çok güzel: Burada uygulama örneğine API planları ithal eden örnek bir uygulama kurulum kodudur. Ek bir avantaj olarak, v1'i desteklemeyi durdurma zamanı geldiğinde, bu sürüm için register_blueprint numaralı çağrıyı kaldırırsınız, v1 paketini kaynaklarınızdan silersiniz ve işiniz biter.

Şimdi, tüm bunların yanı sıra, API'nizi, sürümü revize etme riskini en aza indirecek şekilde tasarlamak için gerçekten çaba göstermelisiniz. Yeni rotalar eklemenin yeni bir API sürümü gerektirmediğini, bir API'yi yeni rotalar ile genişletmenin mükemmel olduğunu düşünün.Ve var olan rotalardaki değişiklikler bazen eski istemcileri etkilemeyecek şekilde tasarlanabilir. Bazen API'yi revize etmek ve işleri değiştirmek için daha fazla özgürlüğe sahip olmak daha az ağrılıdır, ancak ideal olarak bu çok sık gerçekleşmez.

+0

Bu harika çalışıyor, çok teşekkürler! – Keeper

+0

Eksik parçaları temin etmeyi düşünür müsünüz? Blueprints gerçekte nerede oluşturulur? Hangi dosyalarda? Ve Blueprint örneği nasıl görünüyor? Teşekkürler. – thecountofzero

+0

@thecountofzero İşte kitabımdan bir örnek API planı: https://github.com/miguelgrinberg/flasky/tree/master/app/api_1_0 – Miguel

İlgili konular