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
untuktext
dan2
untukwhen
) 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 menetapkanrequired=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
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)