İstemci kitaplığı oluşturma

Google API'leriyle kullanmak üzere çeşitli araçlar oluşturmak için Google API'leri Keşif Hizmeti'ni kullanabilirsiniz. Ancak Discovery belgesinin asıl amacı, Google'ın çeşitli programlama dillerinde istemci kitaplıkları oluşturmasına olanak tanımaktır. Bu belgede, Google API'leri için özel bir istemci kitaplığının nasıl oluşturulacağı açıklanmaktadır.

Kararlı ve eksiksiz özelliklere sahip bir istemci kitaplığı, geliştirilmesi aylar sürebilen karmaşık bir araçtır. Ancak Google API'leri için basit bir istemci kitaplığı oluşturmayla ilgili genel talimatlar üç basit adıma ayrılabilir:

  1. Keşif dokümanını getirme ve API yüzeyini oluşturma
  2. İstek oluşturma
  3. Arama yapma ve yanıtı getirme

Bu adımlar aşağıdaki bölümlerde daha ayrıntılı olarak açıklanmıştır. Bu talimatların kodla nasıl eşlendiğini görmek için Örnekler bölümündeki Simple APIs istemcisi örneğine de göz atabilirsiniz.

Keşif dokümanını getirme

Bir istemci kitaplığını uygulamaya başlamadan önce, geliştirme sürecinde nasıl ilerleyeceğinizi etkileyen bazı temel şartlar vardır. Örneğin, tercih ettiğiniz programlama dili türü belirlenmiş veya belirlenmemiş olabilir. Türü belirlenmişse statik veya dinamik olarak belirlenmiş olabilir. Derlenebilir veya yorumlanabilir. Bu koşullar, Discovery belgesini kullanma ve tüketme yaklaşımınıza yön verecektir.

İlk geliştirme görevi, Discovery belgesini getirmektir. Belgenin tam olarak ne zaman getirileceğine dair stratejiniz, belirlediğiniz şartlara göre belirlenir. Örneğin, statik olarak türü belirlenmiş bir dilde, işlemde Discovery belgesini erken aşamada getirebilir ve ardından Discovery belgesinde açıklanan belirli API'yi işlemek için kod oluşturabilirsiniz. Kesin türü belirlenmiş bir dilde, bazı kodlar oluşturup derlenmiş bir kitaplık oluşturabilirsiniz. Dinamik olarak yazılan bir dilde, programlama yüzeyi kullanılırken API ile arayüz oluşturmak için programlama yapılarını geç oluşturabilirsiniz.

İstek oluşturma

İstek oluşturma işlemi iki ayrı adımdan oluşur:

  1. İstek gövdesini oluşturma.
  2. İstek URL'sini oluşturma.

İstek gövdesini (varsa) dile uygun bir gösterimden doğru tel biçimine dönüştürmeniz gerekir. Örneğin, bir Java istemci kitaplığında, istek verilerinin tür güvenli şekilde işlenmesine olanak tanıyan ve JSON'a serileştirilebilen her istek türü için bir sınıf olabilir.

İstek URL'sinin oluşturulması biraz daha karmaşık bir süreçtir.

API'deki her yöntemin path özelliği, URI Template v04 söz dizimini kullanır. Bu özellik, değişkenler içerebilir. Değişkenler küme parantezleriyle çevrilidir. Değişkenler içeren bir path özelliğinin örneğini aşağıda bulabilirsiniz:

/example/path/var

Yukarıdaki yolda var bir değişkendir. Bu değişkenin değeri, söz konusu yöntem için Discovery belgesinin parameters bölümünden alınır. Her değişken adının parameters nesnesinde karşılık gelen bir değeri vardır. Yukarıdaki örnekte, parameters bölümünde var adlı bir parametre var (ve bunun location özelliği, yol değişkeni olduğunu belirtmek için path'dür).

İstek oluştururken var değerini URL'ye yerleştirmeniz gerekir. Örneğin, kitaplığın kullanıcısı var değerini foo olarak ayarlayan bir seçim yaparsa yeni URL /example/path/foo olur.

Ayrıca path özelliğinin göreli bir URI olduğunu unutmayın. Mutlak URI'yi hesaplamak için aşağıdaki adımları uygulayın:

  1. Konumunuzu (bölge) biliyorsanız ve Discovery belgesinde endpoints özelliği varsa konumunuzun endpoints listesinde yer alıp almadığını kontrol edin. Bu durumda, location değeri sizinkiyle eşleşen endpointUrl öğesini endpoints listesinden alın.
  2. Discovery belgesinde endpoints özelliği yoksa, konumunuz endpoints listesinde yer almıyorsa veya genel uç noktayı hedeflemek istiyorsanız Discovery belgesinin üst düzeyinden rootUrl özelliğini alın.

    Örneğin, Hizmet Kullanımı API'si için keşif dokümanındaki rootUrl özelliği:

    https://serviceusage.googleapis.com/
  3. servicePath öğesini Discovery belgesinin en üst düzeyinden alın. Örneğin, Hizmet Kullanımı API'si için Discovery belgesindeki servicePath özelliği boş.
  4. Bunları birleştirerek şu sonucu elde edersiniz:

    https://serviceusage.googleapis.com/
  5. path özelliğini alın, URI şablonu olarak genişletin ve bu genişletmenin sonuçlarını önceki adımdaki URI ile birleştirin. Örneğin, v1 Service Usage API'nin serviceusage.services.enable yönteminde path özelliğinin değeri v1/{+name}:enable'dir. Dolayısıyla, yöntemin tam URI'si:

    https://serviceusage.googleapis.com/v1/{+name}:enable

Service Usage API'yi çağırmak için API anahtarına ihtiyacınız yoktur. Ancak çağırdığınız API bir API anahtarı gerektiriyorsa API anahtarını URI'nin sorgu dizesine ekleyebilirsiniz:

REQUEST_URI?key=API_KEY

Arama yapma ve yanıtı işleme

İsteği gönderdikten sonra, hem temel HTTP aktarımında hem de API hizmetinden oluşturulan hata mesajlarında oluşabilecek hata koşullarını ele almaya özen göstererek yanıtı uygun dil gösterimine seri durumdan çıkarma işlemini yapmanız gerekir. Hataların biçimi, Google JSON Stil Kılavuzu'nda belgelenmiştir.

Örnekler

Aşağıdaki bölümde, API istemci kitaplığıyla ilgili basit bir örnek verilmiştir.

Simple APIs istemcisi

Aşağıda, Python3 ile yazılmış çok basit bir istemci kitaplığı örneği verilmiştir. İstemci, Service Usage API ile etkileşim kurmak için bir arayüz oluşturur, ardından bu arayüzü kullanarak my-project projesinde Compute Engine API'yi (compute.googleapis.com) etkinleştirir.

import httplib2
import json
import uritemplate
import urllib

# Step 1: Fetch Discovery document
DISCOVERY_URI = "https://serviceusage.googleapis.com/$discovery/rest?version=v1"
h = httplib2.Http()
resp, content = h.request(DISCOVERY_URI)
discovery = json.loads(content)
location = None # Set this to your location if appropriate
use_global_endpoint = True # Set this to False if you want to target the endpoint for your location

# Step 2.a: Construct base URI
BASE_URL = None
if not use_global_endpoint and location:
  if discovery['endpoints']:
    BASE_URL = next((item['endpointUrl'] for item in discovery['endpoints'] if item['location'] == location), None)
if not BASE_URL:
  BASE_URL = discovery['rootUrl']
BASE_URL += discovery['servicePath']

class Collection(object): pass

def createNewMethod(name, method):
  # Step 2.b Compose request
  def newMethod(**kwargs):
    body = kwargs.pop('body', None)
    url = urllib.parse.urljoin(BASE_URL, uritemplate.expand(method['path'], kwargs))
    for pname, pconfig in method.get('parameters', {}).items():
      if pconfig['location'] == 'path' and pname in kwargs:
        del kwargs[pname]
    if kwargs:
      url = url + '?' + urllib.parse.urlencode(kwargs)
    return h.request(url, method=method['httpMethod'], body=body,
                     headers={'content-type': 'application/json'})

  return newMethod

# Step 3.a: Build client surface
def build(discovery, collection):
  for name, resource in discovery.get('resources', {}).items():
    setattr(collection, name, build(resource, Collection()))
  for name, method in discovery.get('methods', {}).items():
    setattr(collection, name, createNewMethod(name, method))
  return collection

# Step 3.b: Use the client
service = build(discovery, Collection())
print (serviceusage.services.enable(name='projects/my-project/services/compute.googleapis.com'))

İstemcinin önemli bileşenleri şunlardır:

  • 1. adım: Discovery belgesini getirin. Service Usage API'nin Discovery belgesi alınır ve bir veri yapısına ayrıştırılır. Python dinamik olarak türü belirlenmiş bir dil olduğundan, Discovery belgesi çalışma zamanında getirilebilir.
  • 2.a adımı: Temel URI'yi oluşturun. Temel URI hesaplanır.
  • 2.adım: İsteği oluşturun. Bir koleksiyonda bir yöntem çağrıldığında, URI şablonu yönteme iletilen parametrelerle genişletilir ve konumu query olan parametreler URL'nin sorgu parametrelerine yerleştirilir. Son olarak, Discovery belgesinde belirtilen HTTP yöntemi kullanılarak oluşturulan URL'ye bir istek gönderilir.
  • 3.a adımı: İstemci yüzeyini oluşturun. İstemci yüzeyi, ayrıştırılmış Discovery belgesinde yinelemeli olarak aşağı inilerek oluşturulur. methods bölümündeki her yöntem için Collection nesnesine yeni bir yöntem eklenir. Koleksiyonlar iç içe yerleştirilebildiğinden resources öğesini ararız ve bulunursa tüm üyeleri için yinelemeli olarak bir Collection nesnesi oluştururuz. Her bir iç içe yerleştirilmiş koleksiyon, Collection nesnesine de özellik olarak eklenir.
  • 3.b adımı: İstemciyi kullanın. Bu, yerleşik API yüzeyinin nasıl kullanıldığını gösterir. Önce Discovery belgesinden bir hizmet nesnesi oluşturulur, ardından projede Compute Engine API'yi etkinleştirmek için Service Usage API kullanılır my-project.