Ringkasan Library RPC Protokol Google

Catatan: Jika ingin menggunakan autentikasi dengan RPC Protokol Google, Anda dapat menggunakan autentikasi yang saat ini tersedia untuk aplikasi App Engine di konsol Google Cloud. Anda juga harus menentukan persyaratan login penggunaan dalam file app.yaml Anda. Metodologi autentikasi lainnya saat ini tidak didukung oleh library RPC Protokol Google dalam App Engine.

Library RPC Protokol Google adalah framework untuk menerapkan layanan remoteprocedure call (RPC) berbasis HTTP. Layanan RPC adalah kumpulan jenis pesan dan metode jarak jauh yang menyediakan cara terstruktur bagi aplikasi eksternal untuk berinteraksi dengan aplikasi web. Karena Anda dapat menentukan pesan dan layanan dalam bahasa pemrograman Python, mudah untuk mengembangkan layanan RPC Protokol, menguji layanan tersebut, dan menskalakannya di App Engine.

Meskipun Anda dapat menggunakan library PCR Protokol Google untuk semua jenis layanan RPC berbasis HTTP, beberapa kasus penggunaan umum mencakup:

  • Memublikasikan API web untuk digunakan oleh pihak ketiga
  • Membuat backend Ajax terstruktur
  • Membuat clone komunikasi server yang berjalan lama

Anda dapat menentukan layanan PCR Protokol Google Protodalam satu class Python yang berisi berapa pun metode jarak jauh yang dideklarasikan. Setiap metode jarak jauh menerima kumpulan parameter tertentu sebagai permintaan dan menampilkan respons tertentu. Parameter permintaan dan respons ini adalah class buatan pengguna yang dikenal sebagai pesan.

Halo Dunia dari RPC Protokol Google

Bagian ini menampilkan contoh definisi layanan yang sangat sederhana yang menerima pesan dari klien jarak jauh. Pesan berisi nama pengguna (HelloRequest.my_name) dan mengirimkan kembali salam untuk orang tersebut (HelloResponse.hello):

from protorpc import messages
from protorpc import remote
from protorpc.wsgi import service

package = 'hello'

# Create the request string containing the user's name
class HelloRequest(messages.Message):
    my_name = messages.StringField(1, required=True)

# Create the response string
class HelloResponse(messages.Message):
    hello = messages.StringField(1, required=True)

# Create the RPC service to exchange messages
class HelloService(remote.Service):

    @remote.method(HelloRequest, HelloResponse)
    def hello(self, request):
        return HelloResponse(hello='Hello there, %s!' % request.my_name)

# Map the RPC service and path (/hello)
app = service.service_mappings([('/hello.*', HelloService)])

Memulai RPC Protokol Google

Bagian ini menunjukkan cara memulai RPC Protokol Google menggunakan aplikasi buku tamu yang dikembangkan di Python. Pengguna dapat mengunjungi buku tamu (juga disertakan sebagai demo di Python SDK) secara online, menulis entri, dan melihat entri dari semua pengguna. Pengguna berinteraksi dengan antarmuka secara langsung, tetapi aplikasi web tidak dapat mengakses informasi tersebut dengan mudah.

Di situlah RPC Protokol berperan. Dalam tutorial ini, kami akan menerapkan RPC Protokol Google ke buku tamu dasar ini, yang memungkinkan aplikasi web lain mengakses data buku tamu. Tutorial ini hanya membahas penggunaan RPC Protokol Google untuk memperluas fungsi buku tamu; terserah Anda apa yang harus dilakukan selanjutnya. Misalnya, Anda mungkin ingin menulis alat yang membaca pesan yang diposting oleh pengguna dan membuat grafik deret waktu dari postingan per hari. Cara Anda menggunakan RPC Protokol bergantung pada aplikasi tertentu Anda; poin pentingnya adalah RPC Protokol Google sangat memperluas apa yang dapat Anda lakukan dengan data aplikasi Anda.

Untuk memulai, Anda akan membuat file, postservice.py, yang menerapkan metode jarak jauh untuk mengakses data di datastore aplikasi buku tamu.

Membuat Modul PostService

Langkah pertama untuk memulai RPC Protokol Google adalah membuat file bernama postservice.py di direktori aplikasi Anda. Anda akan menggunakan file ini untuk menentukan layanan baru, yang mengimplementasikan dua metode—metode pertama yang memposting data dari jarak jauh dan metode lainnya yang mendapatkan data dari jarak jauh.

Anda tidak perlu menambahkan apa pun ke file ini sekarang—tetapi ini adalah file tempat Anda menempatkan semua kode yang ditentukan di bagian berikutnya. Pada bagian berikutnya, Anda akan membuat pesan yang mewakili catatan yang diposting ke datastore aplikasi buku tamu.

Menangani Pesan

Pesan adalah jenis data dasar yang digunakan dalam RPC Protokol Google. Pesan ditentukan dengan mendeklarasikan class yang diwarisi dari class dasar Pesan. Kemudian, tentukan atribut class yang sesuai dengan setiap kolom pesan.

Contohnya, layanan buku tamu memungkinkan pengguna memposting catatan. Jika Anda belum melakukannya, buat file bernama postservice.py di direktori aplikasi Anda. PostService menggunakan class Greeting untuk menyimpan postingan di datastore. Mari tentukan pesan yang mewakili catatan tersebut:

from protorpc import messages

class Note(messages.Message):

    text = messages.StringField(1, required=True)
    when = messages.IntegerField(2)

Pesan catatan ditentukan oleh dua kolom, text dan when. Setiap kolom memiliki jenis tertentu. Kolom teks adalah string unicode yang mewakili konten postingan pengguna ke halaman buku tamu. Kolom when adalah bilangan bulat yang mewakili stempel waktu postingan. Saat menentukan string, kita juga:

  • Memberikan nilai numerik unik pada setiap kolom (1 untuk text dan 2 untuk when) yang digunakan protokol jaringan pokok untuk mengidentifikasi kolom.
  • Menjadikan text sebagai kolom wajib diisi. Kolom bersifat opsional secara default, Anda dapat menandainya sebagai wajib diisi dengan menetapkan required=True. Pesan harus diinisialisasi dengan menetapkan kolom wajib diisi ke sebuah nilai. Metode layanan RPC Protokol Google hanya menerima pesan yang diinisialisasi dengan benar.

Anda dapat menetapkan nilai untuk kolom menggunakan konstruktor class Note:

# Import the standard time Python library to handle the timestamp.
import time

note_instance = Note(text=u'Hello guestbook!', when=int(time.time()))

Anda juga dapat membaca dan menetapkan nilai pada pesan seperti nilai atribut Python normal. Misalnya, untuk mengubah pesan:

print note_instance.text
note_instance.text = u'Good-bye guestbook!'
print note_instance.text
yang menghasilkan hal berikut
Hello guestbook!
Good-bye guestbook!

Menentukan Layanan

Layanan adalah definisi class yang diwarisi dari class dasar Service. Metode layanan jarak jauh ditunjukkan dengan menggunakan dekorator remote. Setiap metode layanan menerima satu pesan sebagai parameternya dan menampilkan satu pesan sebagai responsnya.

Mari tentukan metode pertama PostService. Tambahkan berikut ini ke file postservice.py:

import datetime

from protorpc import message_types
from protorpc import remote

import guestbook

class PostService(remote.Service):

    # Add the remote decorator to indicate the service methods
    @remote.method(Note, message_types.VoidMessage)
    def post_note(self, request):

        # If the Note instance has a timestamp, use that timestamp
        if request.when is not None:
            when = datetime.datetime.utcfromtimestamp(request.when)

        # Else use the current time
        else:
            when = datetime.datetime.now()
        note = guestbook.Greeting(content=request.text, date=when, parent=guestbook.guestbook_key)
        note.put()
        return message_types.VoidMessage()

Dekorator remote menggunakan dua parameter:

  • Jenis permintaan yang diharapkan. Metode post_note() menerima instance Catatan sebagai jenis permintaannya.
  • Jenis respons yang diharapkan. Library RPC Protokol Google dilengkapi dengan jenis bawaan yang disebut VoidMessage (dalam modul protorpc.message_types), yang didefinisikan sebagai pesan tanpa kolom. Ini berarti bahwa pesan post_note() tidak mengembalikan apa pun yang berguna bagi pemanggilnya. Jika kembali tanpa error, pesan dianggap telah diposting.

Karena Note.when adalah kolom opsional, kolom ini mungkin belum ditetapkan oleh pemanggil. Jika hal ini terjadi, nilai when ditetapkan ke Tidak ada. Jika Note.when ditetapkan ke Tidak ada, post_note() akan membuat stempel waktu menggunakan waktu saat pesan diterima.

Instance pesan respons dibuat oleh metode jarak jauh dan menjadi nilai yang ditampilkan metode jarak jauh.

Mendaftarkan Layanan

Anda dapat memublikasikan layanan baru sebagai aplikasi WSGI menggunakan library protorpc.wsgi.service. Buat file baru bernama services.py di direktori aplikasi Anda dan tambahkan kode berikut untuk membuat layanan:

from protorpc.wsgi import service

import postservice

# Map the RPC service and path (/PostService)
app = service.service_mappings([('/PostService', postservice.PostService)])

Sekarang, tambahkan pengendali berikut ke file app.yaml di atas entri generik yang ada:

- url: /PostService.*
  script: services.app
- url: .*
  script: guestbook.app

Menguji Layanan dari Command Line

Setelah membuat layanan, Anda dapat mengujinya menggunakan curl atau alat command line serupa.

# After starting the development web server:
# NOTE: ProtoRPC always expect a POST.
% curl -H \
   'content-type:application/json' \
   -d '{"text": "Hello guestbook!"}'\
   http://localhost:8080/PostService.post_note

Respons JSON kosong menunjukkan bahwa catatan berhasil diposting. Anda dapat melihat catatan tersebut dengan membuka aplikasi buku tamu di browser (http://localhost:8080/).

Menambahkan Kolom Pesan

Setelah dapat memposting pesan ke PostService, mari tambahkan metode baru untuk mendapatkan pesan dari PostService. Pertama, kita akan menentukan pesan permintaan di postservice.py yang menentukan beberapa default dan kolom enum baru yang memberi tahu server cara mengurutkan catatan dalam respons. Tentukan di atas class PostService yang Anda tentukan sebelumnya:

class GetNotesRequest(messages.Message):
    limit = messages.IntegerField(1, default=10)
    on_or_before = messages.IntegerField(2)

    class Order(messages.Enum):
        WHEN = 1
        TEXT = 2
    order = messages.EnumField(Order, 3, default=Order.WHEN)

Saat dikirim ke PostService, pesan ini meminta sejumlah catatan saat atau sebelum tanggal dan dalam urutan tertentu. Kolom limit menunjukkan jumlah maksimum catatan yang akan diambil. Jika tidak ditetapkan secara eksplisit, limit akan ditetapkan secara default ke 10 catatan (seperti yang ditunjukkan oleh argumen kata kunci default=10).

Kolom urutan memperkenalkan class EnumField, yang mengaktifkan jenis kolom enum saat nilai kolom dibatasi ke jumlah terbatas dari nilai simbolis yang diketahui. Dalam hal ini, enum menunjukkan cara mengurutkan catatan dalam respons kepada server. Untuk menentukan nilai enum, buat sub-class class Enum. Setiap nama harus diberi nomor unik untuk jenis tersebut. Setiap angka dikonversi menjadi instance jenis enum dan dapat diakses dari class.

print 'Enum value Order.%s has number %d' % (GetNotesRequest.Order.WHEN.name,
                                             GetNotesRequest.Order.WHEN.number)

Setiap nilai enum memiliki karakteristik khusus yang memudahkan konversi ke nama atau angkanya. Daripada mengakses atribut nama dan angka, cukup konversikan setiap nilai menjadi string atau bilangan bulat.

print 'Enum value Order.%s has number %d' % (GetNotesRequest.Order.WHEN,
                                             GetNotesRequest.Order.WHEN)

Kolom Enum dideklarasikan mirip dengan kolom lain, tetapi kolom tersebut harus memiliki jenis enum sebagai parameter pertamanya sebelum nomor kolom. Kolom Enum juga dapat memiliki nilai default.

Menentukan Pesan Respons

Sekarang mari kita definisikan pesan respons get_notes(). Respons harus berupa kumpulan pesan Catatan. Pesan dapat berisi pesan lain. Dalam kasus kolom Notes.notes yang ditentukan di bawah, kita menunjukkan bahwa ini adalah kumpulan pesan dengan memberikan class Note sebagai parameter pertama ke konstruktor messages.MessageField (sebelum nomor kolom):

class Notes(messages.Message):
    notes = messages.MessageField(Note, 1, repeated=True)

Kolom Notes.notes juga merupakan kolom berulang seperti yang ditunjukkan oleh argumen kata kunci repeated=True. Nilai kolom berulang harus berupa daftar jenis kolom deklarasinya. Dalam hal ini, Notes.notes harus berupa daftar instance Catatan. Daftar dibuat secara otomatis dan tidak dapat ditetapkan ke Tidak Ada.

Sebagai contoh, berikut adalah cara membuat objek Catatan:

response = Notes(notes=[Note(text='This is note 1'),
                        Note(text='This is note 2')])
print 'The first note is:', response.notes[0].text
print 'The second note is:', response.notes[1].text

Mengimplementasikan get_notes

Sekarang kita dapat menambahkan metode get_notes() ke class PostService:

import datetime
import time
from protorpc import remote

class PostService(remote.Service):
    @remote.method(GetNotesRequest, Notes)
    def get_notes(self, request):
        query = guestbook.Greeting.query().order(-guestbook.Greeting.date)

        if request.on_or_before:
            when = datetime.datetime.utcfromtimestamp(
                request.on_or_before)
            query = query.filter(guestbook.Greeting.date <= when)

        notes = []
        for note_model in query.fetch(request.limit):
            if note_model.date:
                when = int(time.mktime(note_model.date.utctimetuple()))
            else:
                when = None
            note = Note(text=note_model.content, when=when)
            notes.append(note)

        if request.order == GetNotesRequest.Order.TEXT:
            notes.sort(key=lambda note: note.text)

        return Notes(notes=notes)