Cloud Endpoints mendukung transcoding protokol sehingga klien dapat mengakses gRPC API Anda menggunakan HTTP/JSON. Extensible Service Proxy (ESP) mentranskode HTTP/JSON ke gRPC.
Panduan ini menjelaskan:
- Cara menggunakan anotasi dalam file
.protountuk menentukan konversi data dari HTTP/JSON ke gRPC - Cara men-deploy layanan di Endpoints untuk menggunakan fitur ini
- Tempat menemukan informasi referensi selengkapnya tentang mendesain dan menerapkan transcoding untuk layanan gRPC
Tutorial ini mengasumsikan bahwa Anda telah menyelesaikan Tutorial gRPC kami dan memahami konsep dasar Endpoint untuk gRPC API.
Mendesain API yang cocok untuk transcoding
Transcoding melibatkan pemetaan permintaan HTTP/JSON dan parameternya ke metode gRPC serta parameter dan jenis nilai yang ditampilkan parameter tersebut. Oleh karena itu, meskipun Anda dapat memetakan permintaan HTTP/JSON ke metode API arbitrer, sebaiknya lakukan hal tersebut jika gRPC API disusun dengan cara yang berorientasi pada resource, seperti API REST HTTP tradisional. Dengan kata lain, Anda mendesain layanan API agar menggunakan sejumlah kecil
metode standar, yang sesuai dengan kata kerja HTTP seperti GET dan PUT,
yang beroperasi pada resource dan koleksi resource layanan,
yang merupakan jenis resource itu sendiri. Metode standar ini adalah List,
Get, Create, Update, dan Delete.
Jika perlu, API juga dapat memiliki beberapa metode kustom non-standar, meskipun metode ini tidak terlalu mudah dipetakan.
Anda dapat mengetahui lebih lanjut desain berorientasi resource dan pemetaan transcoding standar di panduan desain API. Panduan desain ini adalah standar desain yang diikuti di Google saat mendesain API publik seperti Cloud API. Meskipun Anda tidak perlu mengikuti panduan ini untuk menggunakan transcoding gRPC, sebaiknya Anda melakukannya. Secara khusus, halaman berikut dapat membantu Anda memahami prinsip desain ini dan menambahkan pemetaan transcoding yang berguna ke metode Anda:
- Desain berorientasi resource
- Metode standar
- Metode kustom
- Kata kerja HTTP: halaman ini memberikan panduan tambahan untuk penerapan metode Anda jika akan diakses melalui HTTP.
Halaman referensi berikut mungkin juga berguna:
- Referensi aturan HTTP: referensi komprehensif untuk aturan pemetaan HTTP,
Di bagian lain dokumen ini, Anda akan menggunakan contoh Toko Buku yang digunakan dalam
Tutorial kami, yang sudah menggunakan prinsip-prinsip ini.
Toko Buku memiliki koleksi "rak" dari resource "buku", yang dapat
List, Get, Create, atau Delete oleh pengguna.
Tempat mengonfigurasi transcoding
Transcoding gRPC diaktifkan secara default, dan Anda dapat menggunakannya tanpa konfigurasi apa pun. Ikuti petunjuk untuk men-deploy layanan menggunakan transcoding.
Setelah itu, saat Anda mengirim permintaan POST HTTP ke jalur URL
GRPC_SERVICE_FULL_NAME/METHOD_NAME> dengan
nilai kolom pesan permintaan metode (jika ada) sebagai JSON dalam isi permintaan HTTP,
ESP akan mengirim pesan
permintaan ke metode gRPC yang sesuai. Pada contoh sebelumnya,
GRPC_SERVICE_FULL_NAME adalah nama lengkap layanan gRPC
Anda dan METHOD_NAME adalah nama metode.
Misalnya, jika Anda mengirim POST ke URL ListShelves Toko Buku sebagai
berikut:
curl -XPOST http://mydomain/endpoints.examples.bookstore.Bookstore/ListShelves
Anda akan mendapatkan daftar galeri saat ini dalam bentuk JSON.
Namun, dari segi desain antarmuka HTTP, sangat disarankan untuk mengonfigurasi pemetaan secara eksplisit, seperti yang dijelaskan di bagian lain dokumen ini.
Standar konfigurasi gRPC API untuk konfigurasi layanan memungkinkan Anda menentukan
cara data diterjemahkan dari HTTP/JSON ke gRPC. Dua
mekanisme didukung untuk melakukan hal ini: anotasi langsung dalam file
.proto, dan dalam YAML sebagai bagian dari file
konfigurasi gRPC API. Sebaiknya gunakan anotasi proto agar lebih mudah dibaca dan dikelola.
Untuk informasi selengkapnya tentang konfigurasi YAML dan kapan Anda mungkin perlu menggunakannya,
lihat
Mengonfigurasi transcoding di YAML.
Berikut adalah contoh penggunaan pendekatan yang direkomendasikan dari Toko Buku:
// Returns a specific bookstore shelf.
rpc GetShelf(GetShelfRequest) returns (Shelf) {
// Client example - returns the first shelf:
// curl http://DOMAIN_NAME/v1/shelves/1
option (google.api.http) = { get: "/v1/shelves/{shelf}" };
}
...
// Request message for GetShelf method.
message GetShelfRequest {
// The ID of the shelf resource to retrieve.
int64 shelf = 1;
}
Anotasi memberi tahu ESP bahwa membuat permintaan GET HTTP
dengan URL http://mydomain/v1/shelves/1 memanggil metode GetShelf()
server gRPC, dengan GetShelfRequest yang berisi ID galeri yang diminta shelf
(dalam hal ini, 1).
Menambahkan pemetaan transcoding
Bagian ini menjelaskan beberapa anotasi pemetaan tambahan dari contoh
Toko Buku. Ada dua contoh file proto dalam contoh Toko Buku sehingga
Anda dapat men-deploy-nya dengan atau tanpa pemetaan transcoding, dan
membandingkan perbedaan dalam file proto:
bookstore.proto: digunakan dalam Tutorial Endpoint dan tidak memiliki pemetaan transcoding.http_bookstore.proto: binding transcoding ditambahkan.
Untuk panduan yang lebih komprehensif tentang cara menentukan pemetaan transcoding, lihat Metode standar, Metode kustom, dan Referensi aturan HTTP.
Memetakan metode List
Metode List ditentukan dalam file .proto dengan jenis responsnya:
// Returns a list of all shelves in the bookstore. rpc ListShelves(google.protobuf.Empty) returns (ListShelvesResponse) { // Define HTTP mapping. // Client example (Assuming your service is hosted at the given 'DOMAIN_NAME'): // curl http://DOMAIN_NAME/v1/shelves option (google.api.http) = { get: "/v1/shelves" }; } ... message ListShelvesResponse { // Shelves in the bookstore. repeated Shelf shelves = 1; }
Anotasi yang dicetak tebal menentukan pemetaan HTTP untuk metode ini.
option (google.api.http)menentukan bahwa metode ini adalah anotasi pemetaan HTTP gRPC.getmenentukan bahwa metode ini dipetakan ke permintaanGETHTTP."/v1/shelves"adalah template jalur URL (ditambahkan ke domain layanan Anda) yang digunakan permintaanGETuntuk memanggil metode ini. Jalur URL juga dikenal sebagai jalur resource karena biasanya menentukan "hal" atau resource yang ingin Anda gunakan. Dalam hal ini, semua resource rak Toko Buku kami.
Misalnya, jika klien memanggil metode ini dengan mengirim GET ke URL
http://mydomain/v1/shelves, ESP akan memanggil metode gRPC
ListShelves(). Backend gRPC kemudian menampilkan galeri, yang
dikonversi ESP ke format JSON dan ditampilkan ke klien.
Memetakan metode Get
Metode GetShelf Toko Buku ditentukan dalam file .proto dengan
jenis permintaan dan responsnya:
// Returns a specific bookstore shelf. rpc GetShelf(GetShelfRequest) returns (Shelf) { // Client example - returns the first shelf: // curl http://DOMAIN_NAME/v1/shelves/1 option (google.api.http) = { get: "/v1/shelves/{shelf}" }; } ... // Request message for GetShelf method. message GetShelfRequest { // The ID of the shelf resource to retrieve. int64 shelf = 1; } ... // A shelf resource. message Shelf { // A unique shelf id. int64 id = 1; // A theme of the shelf (fiction, poetry, etc). string theme = 2; }
Anotasi yang dicetak tebal menentukan pemetaan HTTP untuk metode ini.
option (google.api.http)menentukan bahwa metode ini adalah anotasi pemetaan HTTP gRPC.getmenentukan bahwa metode ini dipetakan ke permintaanGETHTTP."/v1/shelves/{shelf}"adalah jalur URL untuk permintaan, seperti sebelumnya, tetapi menentukan/v1/shelves/, lalu{shelf}. Notasi kurung kurawal ini memberi tahu ESP bahwa apa pun yang ada di{shelf}adalah nilai yang harus disediakan untukshelfdalam parameterGetShelfRequestmetode.
Jika klien memanggil metode ini dengan mengirim GET ke URL
http://mydomain/v1/shelves/4, ESP akan membuat
GetShelfRequest dengan nilai shelf 4, lalu memanggil metode gRPC
GetShelf() dengan nilai tersebut. Backend gRPC kemudian menampilkan Shelf yang diminta dengan
ID 4, yang dikonversi ESP ke format JSON dan ditampilkan ke
klien.
Metode ini hanya memerlukan satu nilai kolom permintaan yang disediakan oleh
klien, shelf, yang Anda tentukan dalam template jalur URL dengan
notasi "capture" kurung kurawal. Anda juga dapat mengambil beberapa bagian URL
jika diperlukan untuk mengidentifikasi resource yang diminta. Misalnya, metode GetBook
memerlukan klien untuk menentukan ID rak dan ID buku di URL:
// Returns a specific book.
rpc GetBook(GetBookRequest) returns (Book) {
// Client example - get the first book from the second shelf:
// curl http://DOMAIN_NAME/v1/shelves/2/books/1
option (google.api.http) = { get: "/v1/shelves/{shelf}/books/{book}" };
}
...
// Request message for GetBook method.
message GetBookRequest {
// The ID of the shelf from which to retrieve a book.
int64 shelf = 1;
// The ID of the book to retrieve.
int64 book = 2;
}
Selain literal dan tanda kurung kurawal untuk nilai kolom, template jalur URL dapat
menggunakan karakter pengganti untuk menunjukkan bahwa apa pun di bagian URL ini harus
ditangkap. Notasi {shelf} yang digunakan dalam contoh sebelumnya sebenarnya adalah
pintasan untuk {shelf=*}. Anda dapat mengetahui lebih lanjut aturan untuk template
jalur di
referensi aturan HTTP.
Untuk jenis metode ini, tidak ada isi permintaan HTTP yang ditentukan. Anda dapat menemukan panduan selengkapnya untuk memetakan metode Get, termasuk menggunakan parameter kueri, di Metode standar.
Memetakan metode Create
Metode CreateShelf Toko Buku dipetakan ke POST HTTP.
// Creates a new shelf in the bookstore. rpc CreateShelf(CreateShelfRequest) returns (Shelf) { // Client example: // curl -d '{"theme":"Music"}' http://DOMAIN_NAME/v1/shelves option (google.api.http) = { post: "/v1/shelves" body: "shelf" }; } ... // Request message for CreateShelf method. message CreateShelfRequest { // The shelf resource to create. Shelf shelf = 1; } ... // A shelf resource. message Shelf { // A unique shelf id. int64 id = 1; // A theme of the shelf (fiction, poetry, etc). string theme = 2; }
option (google.api.http)menentukan bahwa metode ini adalah anotasi pemetaan HTTP gRPC.postmenentukan bahwa metode ini dipetakan ke permintaanPOSTHTTP."/v1/shelves"adalah jalur URL untuk permintaan, seperti sebelumnya.body: "shelf"digunakan dalam isi permintaan HTTP untuk menentukan resource yang ingin Anda tambahkan, dalam format JSON.
Jadi, misalnya, jika klien memanggil metode ini seperti ini:
curl -d '{"theme":"Music"}' http://DOMAIN_NAME/v1/shelves
ESP menggunakan isi JSON untuk membuat nilai Shelf dengan tema
"Music" untuk CreateShelfRequest, lalu memanggil metode CreateShelf() gRPC. Perhatikan bahwa klien tidak memberikan nilai id untuk Shelf.
ID rak Toko Buku disediakan oleh layanan saat membuat rak baru.
Anda memberikan jenis informasi ini kepada pengguna layanan Anda dalam dokumentasi
API.
Menggunakan karakter pengganti dalam isi
Nama khusus * dapat digunakan dalam pemetaan isi untuk menunjukkan bahwa setiap kolom yang tidak terikat oleh template jalur harus dipetakan ke isi permintaan.
Tindakan ini memungkinkan definisi alternatif metode CreateShelf berikut.
// Creates a new shelf in the bookstore. rpc CreateShelf(CreateShelfRequest) returns (Shelf) { // Client example: // curl -d '{"shelf_theme":"Music", "shelf_size": 20}' http://DOMAIN_NAME/v1/shelves/123 option (google.api.http) = { post: "/v1/shelves/{shelf_id}" body: "*" }; } ... // Request message for CreateShelf method. message CreateShelfRequest { // A unique shelf id. int64 shelf_id = 1; // A theme of the shelf (fiction, poetry, etc). string shelf_theme = 2; // The size of the shelf int64 shelf_size = 3; }
option (google.api.http)menentukan bahwa metode ini adalah anotasi pemetaan HTTP gRPC.postmenentukan bahwa metode ini dipetakan ke permintaanPOSTHTTP."/v1/shelves/{shelf_id}"adalah jalur URL untuk permintaan. Apa pun yang ada di{shelf_id}adalah nilai kolomshelf_iddiCreateShelfRequest.body: "*"digunakan dalam isi permintaan HTTP untuk menentukan semua kolom permintaan yang tersisa kecualishelf_iddalam contoh ini, yaitushelf_themedanshelf_size. Untuk kolom apa pun dalam isi JSON dengan dua nama ini, nilainya akan digunakan di kolomCreateShelfRequestyang sesuai.
Misalnya, jika klien memanggil metode ini seperti ini:
curl -d '{"shelf_theme":"Music", "shelf_size": 20}' http://DOMAIN_NAME/v1/shelves/123
ESP menggunakan isi JSON dan template jalur untuk membuat CreateShelfRequest{shelf_id: 123 shelf_theme: "Music" shelf_size: 20}, lalu menggunakannya untuk memanggil metode CreateShelf() gRPC. Untuk mengetahui detailnya, lihat HttpRule.
Mengonfigurasi transcoding di YAML
Pendekatan alternatif adalah tempat Anda menentukan pemetaan HTTP ke gRPC dalam file YAML konfigurasi gRPC API, bukan dalam file .proto. Anda mungkin perlu mengonfigurasi transcoding dalam file YAML jika memiliki satu definisi API proto yang digunakan di beberapa layanan, dengan pemetaan yang berbeda untuk setiap layanan.
rules di bagian http file YAML menentukan cara memetakan permintaan HTTP/JSON
ke metode gRPC:
http:
rules:
...
#
# 'GetShelf' is available via the GET HTTP verb and '/shelves/{shelf}' URL
# path, where {shelf} is the value of the 'shelf' field of 'GetShelfRequest'
# protobuf message.
#
# Client example - returns the first shelf:
# curl http://DOMAIN_NAME/v1/shelves/1
#
- selector: endpoints.examples.bookstore.Bookstore.GetShelf
get: /v1/shelves/{shelf}
...
Contoh yang lebih lengkap tentang penggunaan pendekatan ini untuk contoh layanan Toko Buku
ada di
api_config_http.yaml.
Men-deploy layanan yang menggunakan transcoding
Men-deploy layanan gRPC yang menggunakan transcoding hampir sama dengan men-deploy layanan gRPC lainnya, dengan satu perbedaan utama. Di
Tutorial, contoh diperlukan untuk menerima permintaan
gRPC dari klien contoh. Namun, jika Anda ingin Toko Buku juga menerima
permintaan HTTP, Anda perlu melakukan beberapa konfigurasi tambahan untuk
ESP. Klien menggunakan protokol HTTP1.1 untuk mengirim permintaan JSON/HTTP
ke ESP, sehingga ESP perlu
dikonfigurasi untuk menggunakan SSL (port SSL dapat mendukung kedua jenis permintaan) atau perlu
mengaktifkan port khusus untuk menerima panggilan ini. Deployment ini
sebagian besar sama dengan dalam tutorial untuk lingkungan yang Anda pilih.
Memastikan aturan HTTP di-deploy
Jika Anda telah mendownload contoh Toko Buku untuk
Tutorial, perhatikan bahwa Anda perlu mendownload
versi file .proto dengan anotasi yang sedikit berbeda,
http_bookstore.proto.
Anda juga perlu meng-clone repositori
googleapis dari GitHub
sebelum menjalankan protoc, karena Anda memerlukan
annotations.proto
di jalur include.
git clone https://github.com/googleapis/googleapis
GOOGLEAPIS_DIR=<your-local-googleapis-folder>
Kemudian, Anda membuat deskripsi .pb baru dari http_bookstore.proto saat
men-deploy
konfigurasi ke Endpoint:
protoc \
--include_imports \
--include_source_info \
--proto_path=${GOOGLEAPIS_DIR} \
--proto_path=. \
--descriptor_set_out=api_descriptor.pb \
http_bookstore.proto
Jika menggunakan metode alternatif untuk mengonfigurasi pemetaan HTTP dalam file YAML konfigurasi gRPC API, Anda juga harus memastikan bahwa aturan yang relevan di-deploy saat men-deploy konfigurasi ke Endpoints. Untuk mencobanya dengan layanan
Toko Buku, aturan dasarnya ada dalam
file
api_config.yaml dan aturan HTTP-nya ada dalam
file
api_config_http.yaml:
gcloud endpoints services deploy api_descriptor.pb api_config.yaml api_config_http.yaml
Menggunakan SSL
Jika SSL diaktifkan untuk komunikasi antara klien dan ESP,
klien dapat menggunakan port yang sama untuk melakukan panggilan gRPC atau HTTP1.1. Anda dapat mengetahui cara menyiapkan SSL untuk layanan Endpoints di Mengaktifkan SSL.
Tentukan port agar ESP dapat menerima panggilan SSL menggunakan tanda --ssl_port
dalam file konfigurasi Google Kubernetes Engine (GKE) atau
perintah docker run (Compute Engine/Docker).
args: [
"--http_port", "8080",
"--ssl_port", "443", # enable SSL port at 443 to serve https requests
"--backend", "grpc://127.0.0.1:8081", # gRPC backend.
"--service", "SERVICE_NAME",
"--rollout_strategy", "managed",
]
Menyiapkan port HTTP1.1
Jika tidak menggunakan SSL, Anda perlu menyiapkan port terpisah untuk permintaan HTTP1.1
karena gRPC dan HTTP1.1 tidak dapat berbagi port yang sama tanpa SSL. Gunakan flag --http_port dalam file konfigurasi GKE atau perintah docker run untuk menentukan port guna menerima panggilan HTTP1.1. Jika Anda juga ingin ESP menerima panggilan gRPC, Anda juga harus menggunakan flag --http2_port untuk menentukan port gRPC.
args: [
"--http_port", "8080", # for HTTP 1.1
"--http2_port", "8090", # for gRPC
"--backend", "grpc://127.0.0.1:8081", # gRPC backend.
"--service", "SERVICE_NAME",
"--rollout_strategy", "managed",
]
Memanggil layanan menggunakan transcoding
Bagian ini menjelaskan penyiapan layanan dan cara melakukan panggilan HTTP ke layanan.
Penyiapan layanan
Ini mengasumsikan bahwa Anda telah menyelesaikan Tutorial layanan gRPC dasar untuk lingkungan yang dipilih dan memiliki cluster GKE atau instance Compute Engine untuk menjalankan contoh.
- Pertama, pastikan Anda telah men-deploy konfigurasi layanan Toko Buku yang mengaktifkan HTTP ke Endpoint, seperti yang dijelaskan dalam Memastikan aturan HTTP di-deploy.
Deploy backend dan ESP seperti yang dijelaskan dalam tutorial untuk platform yang Anda pilih, menggunakan flag
--http_portuntuk mengaktifkan port untuk permintaanHTTP1.1:- Deployment GKE: Ikuti petunjuk dalam
Men-deploy contoh API dan ESP ke cluster,
pastikan tanda
"--http_port"ditentukan dalam file konfigurasi GKE. - Deployment Compute Engine: Ikuti petunjuk dalam artikel Menjalankan contoh API dan ESP dalam penampung Docker.
Pastikan flag
--http_portditentukan dalam perintahdocker runsaat menjalankan penampung Docker ESP yang dikemas sebelumnya.
- Deployment GKE: Ikuti petunjuk dalam
Men-deploy contoh API dan ESP ke cluster,
pastikan tanda
Melakukan panggilan HTTP ke layanan
- Dapatkan alamat IP eksternal ESP dan tetapkan ke
$ESP_IP. Buat permintaan HTTP berikut dengan
curlcurl http://$ESP_IP/v1/shelves(atau gunakan URL yang sama dengan
https://jika Anda menggunakan SSL). Server merespons dengan:{"shelves":[{"id":"1","theme":"Fiction"},{"id":"2","theme":"Fantasy"}]}Jika output menampilkan respons biner, periksa konfigurasi port Anda karena Anda mungkin mengakses port HTTP2, bukan port HTTP.
Coba metode
Create.CreateShelfmemerlukan kunci API, jadi Anda perlu membuat kunci untuk project dan menetapkannya sebagai$KEY. Sekarang panggil:curl -d '{"theme":"Music"}' http://$ESP_IP/v1/shelves?key=$KEYJika memanggil
GetShelveslagi, Anda akan melihat galeri baru.