gRPC vs. REST: Memulai dengan Protokol API Terbaik
Diterbitkan: 2022-07-22Dalam lanskap teknologi saat ini, sebagian besar proyek memerlukan penggunaan API. API menjembatani komunikasi antar layanan yang dapat mewakili satu sistem yang kompleks tetapi juga dapat berada di mesin yang terpisah atau menggunakan beberapa jaringan atau bahasa yang tidak kompatibel.
Banyak teknologi standar menjawab kebutuhan komunikasi antar layanan dari sistem terdistribusi, seperti REST, SOAP, GraphQL, atau gRPC. Sementara REST adalah pendekatan yang disukai, gRPC adalah pesaing yang layak, menawarkan kinerja tinggi, kontrak yang diketik, dan alat yang sangat baik.
Ikhtisar REST
Representational state transfer (REST) adalah sarana untuk mengambil atau memanipulasi data layanan. REST API umumnya dibangun di atas protokol HTTP, menggunakan URI untuk memilih sumber daya dan kata kerja HTTP (misalnya, GET, PUT, POST) untuk memilih operasi yang diinginkan. Badan permintaan dan tanggapan berisi data yang khusus untuk operasi, sementara headernya menyediakan metadata. Sebagai ilustrasi, mari kita lihat contoh sederhana pengambilan produk melalui REST API.
Di sini, kami meminta sumber daya produk dengan ID 11
dan mengarahkan API untuk merespons dalam format JSON:
GET /products/11 HTTP/1.1 Accept: application/json
Dengan permintaan ini, respons kami (tajuk yang tidak relevan dihilangkan) mungkin terlihat seperti:
HTTP/1.1 200 OK Content-Type: application/json { id: 11, name: "Purple Bowtie", sku: "purbow", price: { amount: 100, currencyCode: "USD" } }
Meskipun JSON mungkin dapat dibaca manusia, JSON tidak optimal saat digunakan antar layanan. Sifat berulang dari referensi nama properti—bahkan saat dikompresi—dapat menyebabkan pesan membengkak. Mari kita lihat alternatif untuk mengatasi masalah ini.
Ikhtisar gRPC
gRPC Remote Procedure Call (gRPC) adalah protokol komunikasi lintas platform open-source, berbasis kontrak, yang menyederhanakan dan mengelola komunikasi antar layanan dengan memaparkan serangkaian fungsi ke klien eksternal.
Dibangun di atas HTTP/2, gRPC memanfaatkan fitur seperti streaming dua arah dan Transport Layer Security (TLS) bawaan. gRPC memungkinkan komunikasi yang lebih efisien melalui muatan biner serial. Ini menggunakan buffer protokol secara default sebagai mekanismenya untuk serialisasi data terstruktur, mirip dengan penggunaan JSON oleh REST.
Tidak seperti JSON, bagaimanapun, buffer protokol lebih dari format serial. Mereka termasuk tiga bagian utama lainnya:
- Bahasa definisi kontrak ditemukan di file
.proto
(Kami akan mengikuti proto3, spesifikasi bahasa buffer protokol terbaru.) - Kode fungsi aksesor yang dihasilkan
- Pustaka runtime khusus bahasa
Fungsi jarak jauh yang tersedia pada layanan (didefinisikan dalam file .proto
) terdaftar di dalam node layanan dalam file buffer protokol. Sebagai pengembang, kita dapat mendefinisikan fungsi-fungsi ini dan parameternya menggunakan sistem tipe kaya buffer protokol. Sistem ini mendukung berbagai jenis numerik dan tanggal, daftar, kamus, dan nullable untuk menentukan pesan input dan output kita.
Definisi layanan ini harus tersedia untuk server dan klien. Sayangnya, tidak ada mekanisme default untuk membagikan definisi ini selain menyediakan akses langsung ke file .proto
itu sendiri.
Contoh file .proto
ini mendefinisikan fungsi untuk mengembalikan entri produk, dengan ID:
Pengetikan yang ketat dan pengurutan bidang proto3 membuat deserialisasi pesan jauh lebih sedikit membebani daripada mengurai JSON.
Membandingkan REST vs. gRPC
Untuk rekap, poin paling signifikan saat membandingkan REST vs. gRPC adalah:
ISTIRAHAT | gRPC | |
---|---|---|
lintas platform | Ya | Ya |
Format Pesan | Kustom tetapi umumnya JSON atau XML | Penyangga protokol |
Ukuran Muatan Pesan | Sedang/Besar | Kecil |
Kompleksitas Pemrosesan | Lebih tinggi (penguraian teks) | Lebih rendah (struktur biner yang terdefinisi dengan baik) |
Dukungan Peramban | Ya (asli) | Ya (melalui gRPC-Web) |
Di mana kontrak yang tidak terlalu ketat dan penambahan muatan yang sering diharapkan, JSON dan REST sangat cocok. Ketika kontrak cenderung tetap statis dan kecepatan adalah yang paling penting, gRPC umumnya menang. Di sebagian besar proyek yang pernah saya kerjakan, gRPC terbukti lebih ringan dan lebih berperforma daripada REST.
Implementasi Layanan gRPC
Mari kita buat proyek yang disederhanakan untuk mempelajari betapa sederhananya mengadopsi gRPC.
Membuat Proyek API
Untuk memulai, kita akan membuat proyek .NET 6 di Visual Studio 2022 Community Edition (VS). Kami akan memilih template ASP.NET Core gRPC Service dan memberi nama proyek (kami akan menggunakan InventoryAPI
) dan solusi pertama kami di dalamnya ( Inventory
) .
Sekarang, mari kita pilih. Opsi .NET 6.0 (Dukungan jangka panjang) untuk kerangka kerja kami:
Mendefinisikan Layanan Produk Kami
Sekarang setelah kita membuat proyek, VS menampilkan contoh layanan definisi prototipe gRPC bernama Greeter
. Kami akan menggunakan kembali file inti Greeter
agar sesuai dengan kebutuhan kami.
- Untuk membuat kontrak kita, kita akan mengganti isi dari
greet.proto
dengan Snippet 1, mengganti nama fileproduct.proto
. - Untuk membuat layanan kami, kami akan mengganti konten file
GreeterService.cs
dengan Cuplikan 2, mengganti nama fileProductCatalogService.cs
.
Layanan sekarang mengembalikan produk hardcoded. Untuk membuat layanan berfungsi, kita hanya perlu mengubah pendaftaran layanan di Program.cs
untuk merujuk nama layanan baru. Dalam kasus kami, kami akan mengganti nama app.MapGrpcService<GreeterService>();
ke app.MapGrpcService<ProductCatalogService>();
untuk membuat API baru kami dapat dijalankan.
Peringatan Adil: Bukan Tes Protokol Standar Anda
Meskipun kami mungkin tergoda untuk mencobanya, kami tidak dapat menguji layanan gRPC kami melalui browser yang ditujukan untuk titik akhirnya. Jika kami mencoba ini, kami akan menerima pesan kesalahan yang menunjukkan bahwa komunikasi dengan titik akhir gRPC harus dilakukan melalui klien gRPC.
Membuat Klien
Untuk menguji layanan kami, mari gunakan template Aplikasi Konsol dasar VS dan buat klien gRPC untuk memanggil API. Saya menamai InventoryApp
milik saya.
Untuk kemanfaatan, mari merujuk ke jalur file relatif yang dengannya kita akan membagikan kontrak kita. Kami akan menambahkan referensi secara manual ke file .csproj
. Kemudian, kami akan memperbarui jalur dan mengatur mode Client
. Catatan: Saya sarankan Anda mengenal dan yakin dengan struktur folder lokal Anda sebelum menggunakan referensi relatif.
Berikut adalah referensi .proto
, seperti yang muncul di file proyek layanan dan klien:
File Proyek Layanan (Kode untuk disalin ke file proyek klien) | File Proyek Klien (Setelah menempel dan mengedit) |
---|---|
|
|
Sekarang, untuk memanggil layanan kami, kami akan mengganti konten Program.cs
. Kode kami akan mencapai sejumlah tujuan:
- Buat saluran yang mewakili lokasi titik akhir layanan (port dapat bervariasi, jadi lihat file
launchsettings.json
untuk nilai sebenarnya). - Buat objek klien.
- Buat permintaan sederhana.
- Kirim permintaan.
Mempersiapkan Peluncuran
Untuk menguji kode kami, di VS, kami akan mengklik kanan solusi dan memilih Set Startup Projects . Dalam dialog Halaman Properti Solusi, kita akan:
- Pilih tombol radio di samping Beberapa proyek startup , dan di menu tarik-turun Tindakan, atur kedua proyek (
InventoryAPI
danInventoryApp
) ke Mulai . - Klik Oke .
Sekarang kita dapat memulai solusi dengan mengklik Mulai di toolbar VS (atau dengan menekan tombol F5 ). Dua jendela konsol baru akan ditampilkan: satu untuk memberi tahu kami bahwa layanan sedang mendengarkan, yang lain untuk menunjukkan kepada kami detail produk yang diambil.
Berbagi Kontrak gRPC
Sekarang mari kita gunakan metode lain untuk menghubungkan klien gRPC ke definisi layanan kita. Solusi berbagi kontrak yang paling dapat diakses klien adalah dengan membuat definisi kami tersedia melalui URL. Opsi lain sangat rapuh (file dibagikan melalui jalur) atau memerlukan lebih banyak upaya (kontrak dibagikan melalui paket asli). Berbagi melalui URL (seperti yang dilakukan SOAP dan Swagger/OpenAPI) fleksibel dan membutuhkan lebih sedikit kode.
Untuk memulai, buat file .proto
tersedia sebagai konten statis. Kami akan memperbarui kode kami secara manual karena UI pada tindakan build diatur ke "Protobuf Compiler." Perubahan ini mengarahkan kompiler untuk menyalin file .proto
sehingga dapat disajikan dari alamat web. Jika pengaturan ini diubah melalui UI VS, build akan rusak. Langkah pertama kita adalah menambahkan Cuplikan 4 ke file InventoryAPI.csproj
:
Selanjutnya, kami memasukkan kode dalam Cuplikan 5 di bagian atas file ProductCatalogService.cs
untuk menyiapkan titik akhir untuk mengembalikan file .proto
kami:
Dan sekarang, kami menambahkan Cuplikan 6 tepat sebelum app.Run()
, juga di file ProductCatalogService.cs
:
Dengan menambahkan Cuplikan 4-6, konten file .proto
akan terlihat di browser.
Klien Uji Baru
Sekarang kami ingin membuat klien konsol baru yang akan kami sambungkan ke server kami yang ada dengan VS's Dependency Wizard. Masalahnya adalah wizard ini tidak berbicara HTTP/2. Oleh karena itu, kita perlu menyesuaikan server kita untuk berbicara melalui HTTP/1 dan memulai server. Dengan server kami sekarang membuat file .proto
tersedia, kami dapat membangun klien uji baru yang terhubung ke server kami melalui wizard gRPC.
- Untuk mengubah server kami untuk berbicara melalui HTTP/1, kami akan mengedit file JSON
appsettings.json
kami:- Sesuaikan bidang
Protocol
(dapat ditemukan di jalurKestrel.EndpointDefaults.Protocols
) untuk membacaHttps
. - Simpan file.
- Sesuaikan bidang
- Agar klien baru kami dapat membaca informasi
proto
ini, server harus berjalan. Awalnya, kami memulai klien sebelumnya dan server kami dari dialog Set Startup Projects VS. Sesuaikan solusi server untuk memulai hanya proyek server, lalu mulai solusi. (Sekarang kami telah memodifikasi versi HTTP, klien lama kami tidak dapat lagi berkomunikasi dengan server.) - Selanjutnya, buat klien pengujian baru. Luncurkan instance lain dari VS. Kami akan mengulangi langkah-langkah seperti yang dijelaskan di bagian Membuat Proyek API , tetapi kali ini, kami akan memilih template Aplikasi Konsol . Kami akan memberi nama proyek dan solusi kami
InventoryAppConnected
. - Dengan sasis klien dibuat, kami akan terhubung ke server gRPC kami. Perluas proyek baru di VS Solution Explorer.
- Klik kanan Dependensi dan, di menu konteks, pilih Kelola Layanan Terhubung .
- Pada tab Layanan Terhubung, klik Tambahkan referensi layanan dan pilih gRPC .
- Dalam dialog Tambahkan Referensi Layanan, pilih opsi URL dan masukkan versi
http
dari alamat layanan (ingat untuk mengambil nomor port yang dibuat secara acak darilaunchsettings.json
) . - Klik Selesai untuk menambahkan referensi layanan yang dapat dipelihara dengan mudah.
Jangan ragu untuk memeriksa pekerjaan Anda dengan kode sampel untuk contoh ini. Karena, di bawah tenda, VS telah menghasilkan klien yang sama yang kami gunakan dalam pengujian putaran pertama kami, kami dapat menggunakan kembali konten file Program.cs
dari layanan sebelumnya verbatim.
Saat mengubah kontrak, kita perlu memodifikasi definisi gRPC klien agar sesuai dengan definisi .proto
yang diperbarui. Untuk melakukannya, kita hanya perlu mengakses Layanan Terhubung VS dan menyegarkan entri layanan yang relevan. Sekarang, proyek gRPC kami telah selesai, dan sangat mudah untuk menjaga sinkronisasi layanan dan klien kami.
Kandidat Proyek Anda Berikutnya: gRPC
Implementasi gRPC kami memberikan gambaran langsung tentang manfaat penggunaan gRPC. REST dan gRPC masing-masing memiliki kasus penggunaan idealnya sendiri tergantung pada jenis kontrak. Namun, ketika kedua opsi cocok, saya mendorong Anda untuk mencoba gRPC—ini akan menempatkan Anda di depan kurva di masa depan API.