Cloud Endpoints mendukung transcoding protokol sehingga klien dapat mengakses gRPC API Anda menggunakan HTTP/JSON. Extensible Service Proxy (ESP) men-transcoding HTTP/JSON ke gRPC.
Panduan ini menjelaskan:
- Cara menggunakan anotasi di file
.proto
untuk menentukan konversi data dari HTTP/JSON ke gRPC - Cara men-deploy layanan Anda di Endpoint untuk menggunakan fitur ini
- Tempat menemukan informasi referensi lebih lanjut tentang merancang dan menerapkan transcoding untuk layanan gRPC
Hal ini mengasumsikan bahwa Anda telah menyelesaikan Tutorial gRPC kami dan sudah memahami konsep Endpoint untuk API gRPC dasar.
Mendesain API yang cocok untuk transcoding
Transcoding melibatkan pemetaan permintaan HTTP/JSON dan parameternya ke metode gRPC dan parameternya serta jenis nilai yang ditampilkan. Oleh karena itu, meskipun memetakan permintaan HTTP/JSON ke metode API arbitrer apa pun, ada baiknya jika gRPC API terstruktur dengan cara berorientasi resource, seperti REST API HTTP tradisional. Dengan kata lain, Anda mendesain layanan API sedemikian rupa sehingga menggunakan sejumlah kecil
metode standar, sesuai dengan HTTP verb seperti GET
dan PUT
,
yang beroperasi pada resource dan koleksi resource layanan,
yang juga merupakan jenis resource. Metode standar ini adalah List
,
Get
, Create
, Update
, dan Delete
.
Jika perlu, API juga dapat memiliki beberapa metode kustom non-standar, meskipun tidak mudah dipetakan.
Anda dapat mengetahui informasi selengkapnya tentang desain berorientasi resource dan pemetaan transcoding standar dalam 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 mengikuti panduan ini. Secara khusus, halaman berikut dapat membantu Anda memahami prinsip-prinsip desain ini dan menambahkan pemetaan transcoding yang berguna ke metode Anda:
- Desain yang berorientasi pada resource
- Metode standar
- Metode kustom
- HTTP verbs: halaman ini memberikan panduan tambahan untuk implementasi 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 dapat menggunakan contoh Bookstore yang digunakan dalam
Tutorial kami, yang sudah menggunakan prinsip-prinsip ini.
Toko Buku memiliki koleksi "rak" referensi "buku", yang pengguna dapat List
, Get
, Create
, atau Delete
.
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 mengirimkan 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 mengirimkan 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 metodenya.
Misalnya, jika Anda mengirimkan POST
ke URL ListShelves
Toko Buku seperti
berikut:
curl -XPOST http://mydomain/endpoints.examples.bookstore.Bookstore/ListShelves
Anda akan mendapatkan daftar rak saat ini dalam bentuk JSON.
Namun, sangat disarankan dalam hal desain antarmuka HTTP untuk mengonfigurasi pemetaan secara eksplisit, seperti dijelaskan dalam bagian lain dokumen ini.
Standar konfigurasi gRPC API untuk konfigurasi layanan memungkinkan Anda menentukan
dengan tepat cara data diterjemahkan dari HTTP/JSON ke gRPC. Ada dua mekanisme yang didukung untuk melakukannya: anotasi langsung di file .proto
Anda, dan dalam YAML sebagai bagian dari file konfigurasi gRPC API Anda. Sebaiknya gunakan anotasi proto
agar mudah dibaca dan dikelola.
Untuk mengetahui informasi lebih lanjut tentang konfigurasi YAML dan kapan Anda perlu menggunakannya, baca Mengonfigurasi transcoding di YAML.
Berikut ini contoh menggunakan 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 ini memberi tahu ESP bahwa membuat permintaan GET
HTTP
dengan URL http://mydomain/v1/shelves/1
akan memanggil metode GetShelf()
server gRPC, dengan GetShelfRequest
yang berisi ID rak shelf
yang diminta
(dalam hal ini, 1
).
Menambahkan pemetaan transcoding
Bagian ini menjelaskan beberapa anotasi pemetaan tambahan dari contoh Toko Buku. Ada dua contoh file proto
di contoh Bookstore, sehingga Anda dapat men-deploy keduanya dengan atau tanpa pemetaan transcoding, dan membandingkan perbedaannya dalam file proto
:
bookstore.proto
: digunakan di Tutorial Endpoint dan tidak memiliki pemetaan transcoding.http_bookstore.proto
: binding transcoding ditambahkan.
Untuk panduan yang lebih komprehensif terkait 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)
menetapkan bahwa metode ini adalah anotasi pemetaan HTTP gRPC.get
menentukan bahwa metode ini dipetakan ke permintaanGET
HTTP."/v1/shelves"
adalah template jalur URL (ditambahkan ke domain layanan Anda) yang digunakan permintaanGET
untuk memanggil metode ini. Jalur URL juga dikenal sebagai jalur resource karena biasanya menentukan "objek" atau resource yang ingin Anda gunakan. Dalam hal ini, semua sumber daya rak Bookstore kita.
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 rak, yang
dikonversi oleh ESP ke format JSON dan dikembalikan 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)
menetapkan bahwa metode ini adalah anotasi pemetaan HTTP gRPC.get
menentukan bahwa metode ini dipetakan ke permintaanGET
HTTP."/v1/shelves/{shelf}"
adalah jalur URL untuk permintaan, seperti sebelumnya, tetapi menentukan/v1/shelves/
dan kemudian{shelf}
. Notasi kurung kurawal ini memberi tahu ESP bahwa apa pun yang ada di{shelf}
adalah nilai yang harus diberikan untukshelf
dalam parameterGetShelfRequest
metode.
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()
dengannya. Backend gRPC kemudian menampilkan Shelf
yang diminta dengan
ID 4
, yang dikonversi oleh ESP ke format JSON dan dikembalikan ke
klien.
Metode ini hanya memerlukan satu nilai kolom permintaan yang diberikan oleh klien, shelf
, yang Anda tentukan dalam template jalur URL dengan notasi "capture" melengkung. Anda juga dapat mengambil beberapa bagian URL
jika diperlukan untuk mengidentifikasi resource yang diminta. Misalnya, metode GetBook
mengharuskan klien untuk menentukan ID rak dan ID buku dalam 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 diambil. Notasi {shelf}
yang digunakan dalam contoh sebelumnya sebenarnya merupakan
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
Bookstore 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)
menetapkan bahwa metode ini adalah anotasi pemetaan HTTP gRPC.post
menentukan bahwa metode ini dipetakan ke permintaanPOST
HTTP."/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. Perlu diperhatikan 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.
Gunakan karakter pengganti di 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)
menetapkan bahwa metode ini adalah anotasi pemetaan HTTP gRPC.post
menentukan bahwa metode ini dipetakan ke permintaanPOST
HTTP."/v1/shelves/{shelf_id}"
adalah jalur URL untuk permintaan. Apa pun yang ada di{shelf_id}
adalah nilai kolomshelf_id
diCreateShelfRequest
.body: "*"
digunakan dalam isi permintaan HTTP untuk menentukan semua kolom permintaan yang tersisa kecualishelf_id
dalam contoh ini, dan kolom tersebut adalahshelf_theme
danshelf_size
. Untuk setiap kolom dalam isi JSON yang memiliki kedua nama ini, nilainya akan digunakan dalam kolomCreateShelfRequest
yang 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 alternatifnya adalah Anda menentukan pemetaan HTTP ke gRPC dalam file YAML konfigurasi gRPC API, bukan di 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-beda ditentukan untuk setiap layanan.
rules
di bagian http
file YAML Anda 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 terkait penggunaan pendekatan ini untuk contoh layanan Bookstore
adalah di
api_config_http.yaml
.
Men-deploy layanan yang menggunakan transcoding
Men-deploy layanan gRPC yang menggunakan transcoding sangat mirip dengan men-deploy
layanan gRPC lainnya, dengan satu perbedaan utama. Di
Tutorial, contoh yang diperlukan untuk menerima permintaan
gRPC dari klien contoh. Namun, jika Anda ingin Bookstore 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 harus mengaktifkan port khusus untuk menerima panggilan ini. Sebaliknya, deployment sebagian besar sama dengan yang ada dalam tutorial untuk lingkungan pilihan Anda.
Memastikan aturan HTTP di-deploy
Jika sudah mendownload contoh Bookstore untuk
Tutorial, perhatikan bahwa Anda perlu mendownload
versi file .proto
yang sedikit berbeda dengan anotasi,
http_bookstore.proto
.
Anda juga harus meng-clone repositori googleapis
dari GitHub sebelum menjalankan protoc
, karena Anda memerlukan annotations.proto
di jalur yang disertakan.
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 di file YAML konfigurasi gRPC API, Anda juga perlu memastikan bahwa aturan yang relevan di-deploy saat men-deploy konfigurasi ke Endpoint. Untuk mencobanya dengan layanan Bookstore, aturan dasarnya ada di file api_config.yaml
dan aturan HTTP-nya ada di 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 Endpoint di bagian Mengaktifkan SSL.
Tentukan port ESP untuk menerima panggilan SSL menggunakan flag --ssl_port
di 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
di file konfigurasi GKE atau
perintah docker run
untuk menentukan port untuk
menerima panggilan HTTP1.1
. Jika Anda juga ingin ESP menerima panggilan
gRPC, Anda juga harus menggunakan tanda --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 ini.
Penyiapan layanan
Dengan begitu, Anda dianggap telah menyelesaikan Tutorial layanan gRPC dasar untuk lingkungan yang dipilih dan memiliki cluster GKE atau instance Compute Engine untuk menjalankan contoh tersebut.
- Pertama-tama, pastikan Anda telah men-deploy konfigurasi layanan Bookstore yang mendukung HTTP ke Endpoint, seperti yang dijelaskan dalam Memastikan aturan HTTP di-deploy.
Deploy backend dan ESP seperti yang dijelaskan dalam tutorial untuk platform pilihan Anda, menggunakan flag
--http_port
untuk mengaktifkan port untuk permintaanHTTP1.1
:- Deployment GKE: Ikuti petunjuk dalam Men-deploy contoh API dan ESP ke cluster, dan pastikan flag
"--http_port"
ditentukan dalam file konfigurasi GKE. - Deployment Compute Engine: Ikuti petunjuk di bagian Menjalankan contoh API dan ESP di container Docker.
Pastikan flag
--http_port
ditentukan dalam perintahdocker run
saat menjalankan container Docker ESP yang sudah dikemas sebelumnya.
- Deployment GKE: Ikuti petunjuk dalam Men-deploy contoh API dan ESP ke cluster, dan pastikan flag
Melakukan panggilan HTTP ke layanan
- Dapatkan alamat IP eksternal ESP dan tetapkan ke
$ESP_IP
. Buat permintaan HTTP berikut dengan
curl
curl 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 karena Anda mungkin masuk ke port HTTP2, bukan port HTTP.
Coba metode
Create
.CreateShelf
memerlukan kunci API, sehingga Anda perlu membuat kunci untuk project Anda dan menetapkannya sebagai$KEY
. Sekarang telepon:curl -d '{"theme":"Music"}' http://$ESP_IP/v1/shelves?key=$KEY
Jika memanggil
GetShelves
lagi, Anda akan melihat rak baru.