Běžné vzory použití v Azure SDK pro Go
Balíček Azure Core ( ) v Azure SDK pro Go implementuje několik azcore vzorů, které se používají v celé sadě SDK:
- Tok kanálu HTTP, což je základní mechanismus HTTP používaný klientskými knihovnami sady SDK.
- Stránkování (metody, které vracejí kolekce).
- Dlouhotr běžící operace (LRO).
Stránkování (metody, které vracejí kolekce)
Řada služeb Azure vrací kolekce položek. Vzhledem k tomu, že počet položek může být velký, vrátí tyto klientské metody Pager, který aplikaci umožňuje zpracovat jednu stránku výsledků najednou. Tyto typy jsou definovány jednotlivě pro různé kontexty, ale sdílejí společné charakteristiky, jako je NextPage metoda.
Předpokládejme například, že existuje ListWidgets metoda, která vrací WidgetPager . Pak použijete , jak WidgetPager je znázorněno zde:
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...
}
Příklad implementace Pageru najdete ve zdrojovém souboru SADY SDK zz_generated_pagers.go.
Dlouhotr běžící operace
Dokončení některých operací v Azure může trvat dlouhou dobu, od několika sekund až po několik dnů. Mezi příklady takových operací patří kopírování dat ze zdrojové adresy URL do objektu blob úložiště nebo trénování modelu AI pro rozpoznávání formulářů. Tyto dlouhotrcí operace (LRO) nepomáhou standardnímu toku HTTP relativně rychlé žádosti a odpovědi.
Podle konvence mají metody, které začínají LRO, předponu "Begin" a vracejí metodu Po pro . K pravidelné cyklické dotazování služby, dokud se operace nedokončí, se používá Po ve službě.
Následující příklady ilustrují různé vzory pro zpracování RLRO. Další informace najdete také ve zdrojovém kódu po em.go v sadě SDK.
Blokování volání PollUntilDone
PollUntilDone zpracovává celý rozsah operace dotazování, dokud se nedosáhlo stavu terminálu. Pak vrátí konečnou odpověď HTTP pro operaci dotazování s obsahem datové části v respType rozhraní, které je k dispozici.
resp, err := client.BeginCreate(context.Background(), "blue_widget", nil)
if err != nil {
// Handle error...
}
// Second argument is the polling interval if the endpoint doesn't send a Retry-After header.
w, err = resp.PollUntilDone(context.Background(), 5*time.Second)
if err != nil {
// Handle error...
}
process(w)
Přizpůsobená smyčka dotazování
Poll odešle do koncového bodu dotazování požadavek na dotazování a vrátí odpověď nebo chybu.
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)
Obnovení z předchozí operace
Extrahujte a uložte token obnovení z existujícího souboru Po token.
Pokud chcete cyklické dotazování obnovit, třeba v jiném procesu nebo na jiném počítači, vytvořte novou instanci a pak ji inicializte zavoláte její metodu a předáte jí dříve PollerResponseResume uložený obnovovací token.
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)
Tok kanálu HTTP
Různé klienty poskytují abstrakci přes rozhraní HTTP API služby Azure, aby bylo možné dokončovat kód a zajistit bezpečnost typů při kompilaci. Nemusíte se tedy zabývat mechanismy dopravy nižší úrovně. Můžete si ale přizpůsobit mechanismus přenosu (například opakování a protokolování).
Sada SDK provádí požadavky HTTP prostřednictvím kanáluHTTP . Kanál popisuje posloupnost kroků provedených pro každou cestu odezvy požadavku a odpovědi HTTP.
Kanál se skládá z přenosu společně s libovolným počtem zásad:
- Přenos odešle požadavek do služby a obdrží odpověď.
- Každá zásada dokončí konkrétní akci v kanálu.
Tento diagram znázorňuje tok kanálu:

Všechny klientské balíčky sdílejí balíček Core s názvem . Tento balíček vytvoří kanál HTTP se svou seřazenou sadu zásad, aby se všechny klientské balíčky chovaly konzistentně.
- Při odeslání požadavku HTTP se všechny zásady spustí v pořadí, ve kterém byly přidány do kanálu před odesláním požadavku do koncového bodu HTTP. Tyto zásady obvykle přidávají hlavičky požadavků nebo protokoluly odchozí požadavek HTTP.
- Jakmile služba Azure odpoví, všechny zásady se spustí v opačném pořadí, než se odpověď vrátí do kódu. Většina zásad odpověď ignoruje, ale zásada protokolování odpověď zaznamená. Zásady opakování můžou požadavek znovu vydat, takže vaše aplikace bude odolnější vůči selhání sítě.
Každá zásada má k dispozici potřebná data požadavku nebo odpovědi spolu s potřebným kontextem pro spuštění zásady. Zásady dokončí svoji operaci s danými daty a pak předá řízení dalším zásadám v kanálu.
Ve výchozím nastavení každý balíček klienta vytvoří kanál nakonfigurovaný pro práci s konkrétní službou Azure. Můžete také definovat vlastní zásady a při vytváření klienta je vložit do kanálu HTTP.
Základní zásady kanálu HTTP
Balíček Core poskytuje tři zásady HTTP, které jsou součástí každého kanálu:
Vlastní zásady kanálu HTTP
Můžete definovat vlastní zásady a přidat možnosti nad rámec toho, co je součástí balíčku Core. Pokud chcete například vidět, jak vaše aplikace zachytá selhání sítě nebo služby, můžete vytvořit zásadu, která při vytváření požadavků během testování vloží chybu. Nebo můžete vytvořit zásadu, která napodoní chování služby pro testování.
Pokud chcete vytvořit vlastní zásadu HTTP, definujte vlastní strukturu pomocí Do metody, která implementuje Policy rozhraní:
- Metoda vaší zásady by
Doměla podle potřeby provádět operace s příchozím souborempolicy.Request. Mezi příklady operací patří protokolování, vložení selhání nebo úprava adresy URL požadavku, parametrů dotazu nebo hlaviček požadavku. - Metoda předá (upravený) požadavek dalším zásadám v kanálu voláním
DometodyNextpožadavku. Nextvrátíhttp.Responsea chybu. Vaše zásady mohou provádět jakékoli nezbytné operace, jako je protokolování odpovědi nebo chyby.- Vaše zásady musí vrátit odpověď a chybu zpět předchozí zásadám v kanálu.
Poznámka
Zásady musí být neschůdné. Při šátku zabezpečení může více vousů souběžně přistupovat k jednomu klientskému objektu. Po vytvoření zásady je běžné, že jsou neměnné. Tato neměnnost zajišťuje, že je šmoudlí v bezpečí.
Následující část ukazuje, jak definovat vlastní zásady.
Šablona zásad
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
}
Vlastní přenos HTTP
Přenos odešle požadavek HTTP a vrátí jeho odpověď nebo chybu. Přenos je vyvolán poslední zásadou v kanálu. Jedná se o první zásadu, která zřídí odpověď před vrácením odpovědi nebo chyby zpět do zásad kanálu (v obráceném pořadí).
Ve výchozím nastavení klienti používají http.Client sdílenou knihovnu ze standardní knihovny Go.
Vlastní stavový nebo bezvýcový přenos vytvoříte stejným způsobem jako vlastní zásady. V případě stavu implementujete metodu Do zděděnou z Do V obou případech vaše funkce nebo metoda znovu obdrží , vrátí a provede akce ve stejném pořadí Doazcore.Request jako azCore.Response zásada.
Odstranění pole JSON při vyvolání operace Azure
Operace, JSON-MERGE-PATCH jako je odeslání JSON, které indikují, že se má odstranit pole null (spolu s jeho hodnotou):
{
"delete-me": null
}
Toto chování je v konfliktu s výchozím zařazováním sady SDK, které určuje jako způsob řešení nejednoznačnosti mezi polem, které má být vyloučeno, a jeho omitempty nulovou hodnotou.
type Widget struct {
Name *string `json:",omitempty"`
Count *int `json:",omitempty"`
}
V předchozím příkladu jsou a definovány jako ukazatel na typ, aby bylo možné jednoznačně definovat chybějící hodnotu ( ) a nulovou hodnotu NameCount (0), která může mít sémantické nil rozdíly.
V operaci HTTP PATCH žádné pole, jehož hodnota je , nebude mít vliv na nil hodnotu v prostředku serveru. Při aktualizaci pole widgetu Count zadejte novou hodnotu pro a Count zadat jako Namenil .
Ke splnění požadavku na odeslání JSON null se NullValue použije funkce :
w := Widget{
Count: azcore.NullValue(0).(*int),
}
Tento kód nastaví Count explicitní JSON null . Při odeslání požadavku na server se odstraní pole Count prostředku.