Pola penggunaan umum di SDK Azure untuk Go
Paket Inti Azure (azcore
) di SDK Azure untuk Go mengimplementasikan beberapa pola yang diterapkan di seluruh SDK:
- Aliran alur HTTP, yang merupakan mekanisme HTTP yang mendasari yang digunakan oleh pustaka klien SDK.
- Paginasi (metode yang menampilkan koleksi).
- Operasi jangka panjang (LRO).
Paginasi (metode yang menampilkan koleksi)
Banyak layanan Azure menampilkan koleksi item. Karena jumlah item bisa saja besar, metode klien ini menampilkan Penyeranta, yang memungkinkan aplikasi Anda memproses satu halaman hasil dalam satu waktu. Jenis-jenis ini didefinisikan secara individual untuk berbagai konteks tetapi memiliki karakteristik yang sama, seperti metode NextPage
.
Misalnya, ada metode ListWidgets
yang menampilkan WidgetPager
. Maka Anda akan menggunakan WidgetPager
seperti yang ditunjukkan di sini:
func (c *WidgetClient) ListWidgets(options *ListWidgetOptions) WidgetPager {
// ...
}
pager := client.ListWidgets(options)
for pager.NextPage(ctx) {
for _, w := range pager.PageResponse().Widgets {
process(w)
}
}
if pager.Err() != nil {
// Handle error...
}
Operasi jangka panjang
Beberapa operasi di Azure dapat memakan waktu yang lama untuk diselesaikan, dari beberapa detik hingga beberapa hari. Contoh operasi tersebut termasuk menyalin data dari URL sumber ke blob penyimpanan atau melatih model AI untuk mengenali formulir. Operasi jangka panjang (LMO) ini sangat cocok untuk alur HTTP standar dari permintaan dan respons yang relatif cepat.
Dengan konvensi, metode yang memulai LRO diawali dengan "Mulai" dan menampilkan Poller. Poller digunakan untuk secara berkala melakukan polling layanan sampai operasi selesai.
Contoh-contoh berikut menggambarkan berbagai pola dalam menangani LRO. Anda juga dapat mempelajari lebih lanjut dari kode sumber poller.go di SDK.
Memblokir panggilan ke PollUntilDone
PollUntilDone
menangani seluruh rentang operasi polling sampai status terminal tercapai. Kemudian mengembalikan respons HTTP akhir untuk operasi polling dengan konten payload di respType
antarmuka.
resp, err := client.BeginCreate(context.Background(), "blue_widget", nil)
if err != nil {
// Handle error...
}
w, err = resp.PollUntilDone(context.Background(), nil)
if err != nil {
// Handle error...
}
process(w)
Perulangan polling yang disesuaikan
Poll
mengirimkan permintaan polling ke titik akhir polling dan menampilkan respons atau kesalahan.
resp, err := client.BeginCreate(context.Background(), "green_widget")
if err != nil {
// Handle error...
}
poller := resp.Poller
for {
resp, err := poller.Poll(context.Background())
if err != nil {
// Handle error...
}
if poller.Done() {
break
}
// Do other work while waiting.
}
w, err := poller.FinalResponse(ctx)
if err != nil {
// Handle error...
}
process(w)
Melanjutkan dari operasi sebelumnya
Ekstrak dan simpan token lanjutkan dari Poller yang sudah ada.
Untuk melanjutkan polling, mungkin dalam proses yang lain atau di komputer lain, buat instans PollerResponse
baru, kemudian inisialisasi dengan memanggil metode Resume
terkait, yang akan meneruskan token resume yang disimpan sebelumnya.
poller := resp.Poller
tk, err := poller.ResumeToken()
if err != nil {
// Handle error...
}
resp = WidgetPollerResponse()
// Resume takes the resume token as an argument.
err := resp.Resume(tk, ...)
if err != nil {
// Handle error...
}
for {
resp, err := poller.Poll(context.Background())
if err != nil {
// Handle error...
}
if poller.Done() {
break
}
// Do other work while waiting.
}
w, err := poller.FinalResponse(ctx)
if err != nil {
// Handle error...
}
process(w)
Aliran alur HTTP
Berbagai klien SDK menyediakan abstraksi atas REST API Azure untuk mengaktifkan penyelesaian kode dan keamanan jenis kompilasi-waktu sehingga Anda tidak perlu berurusan dengan mekanika transportasi tingkat bawah melalui HTTP. Namun, Anda dapat menyesuaikan mekanika transportasi (seperti percobaan ulang dan pengelogan).
SDK membuat permintaan melalui alur HTTP. Alur menjelaskan urutan langkah-langkah yang dilakukan untuk setiap perjalanan bolak-balik permintaan-respons.
Alur terdiri dari transportasi bersama dengan sejumlah kebijakan:
- Transportasi mengirimkan permintaan ke layanan dan menerima tanggapan.
- Setiap kebijakan menyelesaikan tindakan tertentu dalam alur.
Diagram berikut mengilustrasikan alur:
Semua paket klien berbagi paket Inti bernama azcore
. Paket ini membangun alur HTTP dengan serangkaian kebijakan terkait yang disusun, memastikan bahwa semua paket klien berperilaku konsisten.
Ketika permintaan HTTP dikirim, semua kebijakan berjalan sesuai urutan di mana mereka ditambahkan ke alur sebelum permintaan dikirim ke titik akhir HTTP. Kebijakan ini biasanya menambahkan header permintaan atau mencatat permintaan keluar.
Setelah layanan Azure merespons, semua kebijakan berjalan dalam urutan terbalik sebelum respons kembali ke kode Anda. Sebagian besar kebijakan mengabaikan respons, tetapi kebijakan pengelogan mencatat respons. Kebijakan coba lagi mungkin menghasilkan kembali permintaan, membuat aplikasi Anda lebih tahan terhadap kegagalan jaringan.
Setiap kebijakan dilengkapi dengan data respons atau permintaan yang diperlukan, bersama dengan konteks apa pun yang diperlukan untuk menjalankan kebijakan. Kebijakan ini menyelesaikan operasinya dengan data yang diberikan, kemudian meneruskan kontrol ke kebijakan berikutnya dalam alur.
Secara default, setiap paket klien membuat alur yang dikonfigurasi untuk bekerja dengan layanan Azure tertentu. Anda juga dapat menentukan kebijakan kustom Anda sendiri dan memasukkannya ke dalam alur HTTP saat membuat klien.
Kebijakan alur HTTP Inti
Paket Inti menyediakan tiga kebijakan HTTP yang merupakan bagian dari setiap alur:
Kebijakan alur HTTP kustom
Anda dapat menentukan kebijakan kustom Anda sendiri untuk menambahkan kemampuan di luar konten paket Core. Misalnya, untuk melihat cara aplikasi Anda menangani kegagalan jaringan atau layanan, Anda dapat membuat kebijakan yang menyuntikkan kesalahan saat permintaan dibuat selama pengujian. Atau Anda dapat membuat kebijakan yang meniru perilaku layanan untuk pengujian.
Untuk membuat kebijakan HTTP kustom, tentukan struktur Anda sendiri dengan metode Do
yang mengimplementasikan antarmuka Policy
:
- Metode
Do
kebijakan Anda harus melakukan operasi sesuai kebutuhan padapolicy.Request
yang masuk. Contoh operasi termasuk pengelogan, menyuntikkan kegagalan, atau memodifikasi URL permintaan, parameter kueri, atau header permintaan. - Metode
Do
meneruskan permintaan (yang dimodifikasi) ke kebijakan berikutnya dalam alur dengan memanggil metodeNext
permintaan. Next
menampilkanhttp.Response
dan kesalahan. Kebijakan Anda dapat melakukan operasi apa pun yang diperlukan, seperti mencatat respons/kesalahan.- Kebijakan Anda harus mengembalikan respons dan kesalahan kembali ke kebijakan sebelumnya dalam alur.
Catatan
Kebijakan harus goroutine-aman. Keamanan goroutine memungkinkan beberapa goroutine untuk mengakses satu objek klien secara bersamaan. Tidak dapat diubahnya kebijakan setelah dibuat merupakan hal yang umum. Keabadian ini memastikan goroutine aman.
Templat kebijakan kustom
Kode berikut dapat digunakan sebagai titik awal untuk menentukan kebijakan kustom.
type MyPolicy struct {
LogPrefix string
}
func (m *MyPolicy) Do(req *policy.Request) (*http.Response, error) {
// Mutate/process request.
start := time.Now()
// Forward the request to the next policy in the pipeline.
res, err := req.Next()
// Mutate/process response.
// Return the response & error back to the previous policy in the pipeline.
record := struct {
Policy string
URL string
Duration time.Duration
}{
Policy: "MyPolicy",
URL: req.Raw().URL.RequestURI(),
Duration: time.Duration(time.Since(start).Milliseconds()),
}
b, _ := json.Marshal(record)
log.Printf("%s %s\n", m.LogPrefix, b)
return res, err
}
func ListResourcesWithPolicy(subscriptionID string) error {
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
return err
}
mp := &MyPolicy{
LogPrefix: "[MyPolicy]",
}
options := &arm.ConnectionOptions{}
options.PerCallPolicies = []policy.Policy{mp}
options.Retry = policy.RetryOptions{
RetryDelay: 20 * time.Millisecond,
}
con := arm.NewDefaultConnection(cred, options)
if err != nil {
return err
}
client := armresources.NewResourcesClient(con, subscriptionID)
pager := client.List(nil)
for pager.NextPage(context.Background()) {
if err := pager.Err(); err != nil {
log.Fatalf("failed to advance page: %v", err)
}
for _, r := range pager.PageResponse().ResourceListResult.Value {
printJSON(r)
}
}
return nil
}
Transportasi HTTP kustom
Transportasi mengirimkan permintaan dan menampilkan respons/kesalahannya. Kebijakan pertama untuk menangani permintaan juga merupakan kebijakan terakhir yang menangani respons sebelum mengembalikan respons/kesalahan kembali ke kebijakan alur (dalam urutan terbalik). Kebijakan terakhir dalam alur memanggil transportasi.
Secara default, klien menggunakan berbagi http.Client
dari pustaka standar Go.
Anda membuat transportasi berstatus atau tanpa status kustom dengan cara yang sama seperti Anda membuat kebijakan kustom. Dalam kasus berstatus, Anda menerapkan metode Do
yang diwarisi dari antarmuka Transporter. Dalam kedua kasus, fungsi atau metode Do
Anda kembali menerima azcore.Request
, mengembalikan azCore.Response
, dan melakukan tindakan dalam urutan yang sama dengan kebijakan.
Cara menghapus bidang JSON saat Anda memanggil operasi Azure
Operasi seperti JSON-MERGE-PATCH
mengirim null
JSON untuk menunjukkan bidang harus dihapus (bersama dengan nilainya):
{
"delete-me": null
}
Perilaku ini bertentangan dengan penyusunan default SDK yang menentukan omitempty
sebagai cara untuk menyelesaikan ambiguitas antara bidang yang akan dikecualikan dan nilai nolnya.
type Widget struct {
Name *string `json:",omitempty"`
Count *int `json:",omitempty"`
}
Dalam contoh sebelumnya, Name
dan Count
didefinisikan sebagai pointer-ke-jenis untuk membedakan antara nilai yang hilang (nil
) dan nilai nol (0), yang mungkin memiliki perbedaan semantik.
Dalam operasi PATCH HTTP, bidang apa pun dengan nilai nil
tidak memengaruhi nilai dalam sumber daya server. Saat memperbarui bidang Count
Widget, tentukan nilai baru untuk Count
, membiarkan Name
sebagai nil
.
Untuk memenuhi persyaratan pengiriman null
JSON, fungsi NullValue
digunakan:
w := Widget{
Count: azcore.NullValue(0).(*int),
}
Kode ini mengatur Count
ke null
JSON eksplisit. Saat permintaan dikirim ke server, bidang sumber daya Count
dihapus.