Mengakses App Engine dengan API Jarak Jauh

ID region

REGION_ID adalah kode singkat yang ditetapkan Google berdasarkan region yang Anda pilih saat membuat aplikasi. Kode ini tidak sesuai dengan negara atau provinsi, meskipun beberapa ID region mungkin tampak mirip dengan kode negara dan provinsi yang umum digunakan. Untuk aplikasi yang dibuat setelah Februari 2020, REGION_ID.r disertakan dalam URL App Engine. Untuk aplikasi lama yang dibuat sebelum tanggal tersebut, ID region bersifat opsional dalam URL.

Pelajari ID region lebih lanjut.

Library API Jarak Jauh memungkinkan setiap klien Python mengakses layanan yang tersedia untuk aplikasi App Engine.

Misalnya, jika aplikasi App Engine Anda menggunakan Datastore atau Google Cloud Storage, klien Python dapat mengakses resource penyimpanan tersebut menggunakan API Jarak Jauh.

Anda dapat menggunakan API Jarak Jauh untuk mengakses penyimpanan data aplikasi dari aplikasi yang berjalan di komputer lokal, atau dari shell API Jarak Jauh interaktif lokal. API Jarak Jauh berinteraksi dengan layanan nyata, sehingga akses ini menggunakan kuota dan resource yang dapat ditagih.

Mengaktifkan akses API Jarak Jauh di aplikasi Anda

Cara termudah untuk mengaktifkan API Jarak Jauh untuk aplikasi Anda adalah dengan menggunakan perintah builtins dalam file app.yaml untuk aplikasi Anda, yang menentukan URL default /_ah/remote_api/. Namun, Anda dapat menggunakan perintah url dalam file yang sama tersebut untuk menentukan beberapa URL lain.

bawaan

Perintah builtins dalam file app.yaml membuat API Jarak Jauh tersedia di URL default /_ah/remote_api:

runtime: python27
api_version: 1
threadsafe: true

builtins:
- remote_api: on

URL

Penggunaan perintah url di app.yaml memungkinkan Anda menentukan URL yang berbeda untuk digunakan dengan API Jarak Jauh:

- url: /some-URL/*
  script: google.appengine.ext.remote_api.handler.application

Pastikan Anda men-deploy aplikasi ke App Engine setelah melakukan perubahan ini.

Menggunakan shell API Jarak Jauh

Python SDK menyertakan shell API Jarak Jauh yang memungkinkan Anda memanggil perintah Python pada layanan App Engine yang digunakan oleh aplikasi Anda. Anda tidak perlu memberikan autentikasi tambahan, karena metode ini otomatis menggunakan kredensial yang sama dengan yang Anda gunakan untuk mengupload aplikasi ke App Engine.

Untuk memulai shell API Jarak Jauh:

  1. Panggil perintah berikut dari jendela terminal di komputer lokal Anda:

    SDK-INSTALL-DIRECTORY/remote_api_shell.py -s YOUR-PROJECT-ID. REGION_ID.r.appspot.com

    Ganti [SDK-INSTALL-DIRECTORY] dengan jalur ke App Engine SDK untuk Python, dan [YOUR-PROJECT-ID] dengan project ID Anda.

  2. Di shell interaktif yang ditampilkan, panggil perintah Python yang ingin Anda jalankan. Misalnya, jika aplikasi Anda menggunakan Datastore, Anda dapat memanggil kueri ndb berikut untuk mengambil 10 kumpulan data:

     >>> from google.appengine.ext import ndb
     >>>
     >>> # Fetch 10 keys from the datastore
     >>> ndb.Query().fetch(10, keys_only=True)
    

Menggunakan API Jarak Jauh di klien lokal

Anda juga dapat menggunakan API Jarak Jauh di aplikasi lokal untuk mengakses layanan yang digunakan oleh aplikasi yang berjalan di App Engine.

Untuk menggunakan API Jarak Jauh di aplikasi lokal:

  1. Aktifkan API jarak jauh.

  2. Ekspor variabel lingkungan PYTHONPATH untuk direktori Python Anda, misalnya:

     export PYTHONPATH=/usr/somedir/v3/bin/python2.7
    

    Ganti jalur tersebut dengan nilai sebenarnya untuk lokasi Python Anda.

  3. Tambahkan lokasi App Engine SDK untuk Python Anda ke PYTHONPATH:

     export GAE_SDK_ROOT="/usr/local/home/mydir/google_appengine"
     export PYTHONPATH=${GAE_SDK_ROOT}:${PYTHONPATH}
    

    Ganti jalur SDK yang ditampilkan di atas dengan jalur sebenarnya ke App Engine SDK.

  4. Dalam kode klien, impor dev_appserver dan panggil dev_appserver.fix_sys_path() untuk memastikan semua modul App Engine SDK diimpor dengan benar:

    try:
        import dev_appserver
        dev_appserver.fix_sys_path()
  5. Tambahkan kode remote_api_stub berikut ke aplikasi Anda, dan pastikan Anda meneruskan project ID ke dalam kode Anda:

    remote_api_stub.ConfigureRemoteApiForOAuth(
        '{}.appspot.com'.format(project_id),
        '/_ah/remote_api')

    Jika tidak menggunakan URL default /_ah/remote_api untuk API Jarak Jauh, Anda harus mengubah kode di atas untuk mencerminkan URL yang Anda gunakan. Untuk definisi dan dokumentasi remote_api_stub.ConfigureRemoteApiForOAuth, lihat file SDK [SDK-INSTALL-DIRECTORY]/google/appengine/ext/remote_api/remote_api_stub.py.

  6. Tambahkan impor App Engine dan kode Python yang diperlukan untuk mengakses layanan App Engine yang diinginkan. Kode contoh berikut mengakses penyimpanan data project:

    
    import argparse
    
    try:
        import dev_appserver
        dev_appserver.fix_sys_path()
    except ImportError:
        print('Please make sure the App Engine SDK is in your PYTHONPATH.')
        raise
    
    from google.appengine.ext import ndb
    from google.appengine.ext.remote_api import remote_api_stub
    
    def main(project_id):
        remote_api_stub.ConfigureRemoteApiForOAuth(
            '{}.appspot.com'.format(project_id),
            '/_ah/remote_api')
    
        # List the first 10 keys in the datastore.
        keys = ndb.Query().fetch(10, keys_only=True)
    
        for key in keys:
            print(key)
    
    if __name__ == '__main__':
        parser = argparse.ArgumentParser(
            description=__doc__,
            formatter_class=argparse.RawDescriptionHelpFormatter)
        parser.add_argument('project_id', help='Your Project ID.')
    
        args = parser.parse_args()
    
        main(args.project_id)
  7. Setelah aplikasi Anda di-deploy ke App Engine, mulai klien API Jarak Jauh Anda:

     python your-client.py YOUR-PROJECT-ID
    

    Mengganti your-client.py dengan modul klien, dan YOUR-PROJECT-ID dengan project ID Anda. Hal ini mengasumsikan bahwa klien Anda menerima project ID sebagai input command line, dengan mengikuti contoh kode client.py.

Batasan dan praktik terbaik

Modul remote_api secara optimal dirancang untuk sedapat mungkin, berperilaku sama persis dengan datastore App Engine native. Dalam beberapa kasus, ini berarti melakukan hal-hal yang kurang efisien dibandingkan yang seharusnya. Saat menggunakan remote_api, berikut beberapa hal yang perlu diingat:

Setiap permintaan datastore memerlukan proses dua arah

Karena Anda mengakses datastore melalui HTTP, terdapat sedikit lebih banyak overhead dan latensi dibandingkan ketika Anda mengaksesnya secara lokal. Untuk mempercepat dan mengurangi beban, coba batasi jumlah perjalanan dua arah yang Anda lakukan dengan mengelompokkan get dan put, serta mengambil batch entity dari kueri. Ini merupakan saran yang bagus tidak hanya untuk remote_api, tetapi juga untuk menggunakan datastore secara umum, karena operasi batch hanya dianggap sebagai operasi Datastore tunggal. Misalnya, daripada menulis ini:

for key in keys:
  rec = key.get()
  rec.foo = bar
  rec.put()

Anda bisa melakukan ini:

records = ndb.get_multi(keys)
for rec in records:
  rec.foo = bar
  ndb.put_multi(records)

Kedua contoh tersebut memiliki efek yang sama, tetapi opsi kedua hanya memerlukan dua perjalanan dua arah secara total, sedangkan opsi pertama memerlukan dua perjalanan dua arah untuk setiap entity.

Permintaan ke remote_api menggunakan kuota

Karena remote_api beroperasi melalui HTTP, setiap panggilan datastore yang Anda lakukan akan menyebabkan penggunaan kuota untuk permintaan HTTP, byte masuk dan keluar, serta kuota datastore biasa. Ingatlah hal ini jika Anda menggunakan remote_api untuk melakukan update massal.

Batas API sebesar 1 MB berlaku

Seperti saat berjalan secara native, batas 1 MB untuk permintaan dan respons API masih berlaku. Jika entity Anda sangat besar, Anda mungkin perlu membatasi jumlah yang Anda ambil atau tempatkan pada satu waktu agar tetap di bawah batas ini. Sayangnya, hal ini bertentangan dengan meminimalkan perjalanan dua arah. Oleh karena itu, saran terbaiknya adalah menggunakan batch terbesar yang Anda bisa tanpa melampaui batasan ukuran permintaan atau respons. Namun, bagi sebagian besar entity, hal ini mungkin tidak menjadi masalah.

Hindari melakukan iterasi pada kueri

Satu pola umum dengan akses datastore adalah sebagai berikut:

q = MyModel.query()
for entity in q:
  # Do something with entity

Saat Anda melakukan ini, SDK akan mengambil entity dari datastore dalam batch berisi 20, dengan mengambil batch baru setiap kali SDK menggunakan batch yang sudah ada. Karena setiap batch harus diambil dalam permintaan terpisah oleh remote_api, metode ini tidak dapat melakukannya secara efisien. Sebagai gantinya, remote_api mengeksekusi kueri yang benar-benar baru untuk setiap batch, menggunakan fungsi offset untuk mendapatkan hasil lebih lanjut.

Jika mengetahui jumlah entity yang diperlukan, Anda dapat melakukan seluruh pengambilan dalam satu permintaan dengan meminta jumlah yang diperlukan:

entities = MyModel.query().fetch(100)
for entity in entities:
  # Do something with entity

Jika tidak mengetahui jumlah entity yang diinginkan, Anda dapat menggunakan cursors untuk melakukan iterasi secara efisien pada kumpulan hasil yang besar. Hal ini juga memungkinkan Anda menghindari batas 1000 entity yang diberlakukan pada kueri datastore normal.

Transaksi kurang efisien

Untuk mengimplementasikan transaksi melalui remote_api, metode ini mengumpulkan informasi tentang entity yang diambil di dalam transaksi, bersama dengan salinan entity yang ditempatkan atau dihapus di dalam transaksi. Ketika transaksi melalui proses commitment, semua informasi ini akan dikirimkan ke server App Engine, di mana transaksi harus mengambil kembali semua entity yang digunakan dalam transaksi, memverifikasi bahwa entity tersebut belum dimodifikasi, kemudian menempatkan dan menghapus semua perubahan transaksi dan melakukan commitment pada transaksi. Jika terjadi konflik, server akan melakukan roll back transaksi dan memberi tahu klien, kemudian harus mengulangi prosesnya dari awal.

Pendekatan ini berfungsi dengan baik, dan menduplikasi fungsi yang dihasilkan oleh transaksi di datastore lokal, tetapi tidak efisien. Artinya, gunakan transaksi jika diperlukan, tetapi coba batasi jumlah dan kompleksitas transaksi yang Anda jalankan demi efisiensi.