Esercizio - Usare un gestore personalizzato per creare un'app

Completato

In questo esercizio si creerà ed eseguirà un'app serverless usando Go.

Eseguire lo scaffolding dell'app

Iniziare con lo scaffolding dell'app, usando l'estensione Funzioni di Azure in Visual Studio Code.

  1. Selezionare Visualizza>Riquadro comandi.
  2. Selezionare Azure Functions: Create New Project (Q#: Crea nuovo progetto).
  3. Selezionare una cartella, in genere la cartella corrente.
  4. In Selezionare un linguaggio specificare Gestore personalizzato.
  5. In Selezionare un modello per la prima funzione specificare HttpTrigger.
  6. Assegnare un nome all'app, ad esempio hello.
  7. Selezionare un livello di autorizzazione anonimo. È possibile modificare questa impostazione in un secondo momento, se necessario.

A questo punto è disponibile un progetto simile al seguente:

hello/
  function.json
.funcignore
.gitignore
host.json
local.settings.json
proxies.json

Creare l'app

La sequenza successiva di passaggi consiste nella creazione di un'app in grado di rispondere a un trigger HTTP.

  1. Creare un file denominato server.go nella radice del progetto.

  2. Includere in server.go il contenuto seguente:

    package main
    
    import (
     "fmt"
     "io/ioutil"
     "log"
     "net/http"
     "os"
    )
    

    Il codice precedente importa tutte le librerie necessarie per creare un'app HTTP e cercare le variabili di ambiente.

  3. Aggiungere il codice seguente dopo le istruzioni di importazione:

    func main() {
      customHandlerPort, exists := os.LookupEnv("FUNCTIONS_CUSTOMHANDLER_PORT")
      if !exists {
        customHandlerPort = "8080"
      }
      mux := http.NewServeMux()
      // mux.HandleFunc("/api/hello", helloHandler)
      fmt.Println("Go server Listening on: ", customHandlerPort)
      log.Fatal(http.ListenAndServe(":"+customHandlerPort, mux))
    }
    

    La funzione main() viene richiamata da sola. La prima riga del codice indica come verrà letta dalla variabile di ambiente FUNCTIONS_CUSTOM_HANDLER_PORT:

    customHandlerPort, exists := os.LookupEnv("FUNCTIONS_CUSTOMHANDLER_PORT")
    

    Successivamente, la funzione verifica se la porta esiste. In caso contrario, alla funzione viene assegnata la porta 8080:

    if !exists {
      customHandlerPort = "8080"
    }
    

    Il codice successivo crea un'istanza del server HTTP:

    mux := http.NewServeMux()
    

    L'ultima riga rilevante è quella che inizia ad ascoltare su una porta specifica e segnala che è pronta per ricevere richieste, con il metodo ListenAndServe() :

    log.Fatal(http.ListenAndServe(":"+customHandlerPort, mux))
    
  4. Si aggiungerà ora il codice rimanente. Prima di tutto, individuare la riga seguente e rimuovere il commento:

    // mux.HandleFunc("/api/hello", helloHandler)
    
  5. Tra le istruzioni di importazione e la funzione main() aggiungere il codice seguente:

    func helloHandler(w http.ResponseWriter, r *http.Request) {
      w.Header().Set("Content-Type", "application/json")
      if r.Method == "GET" {
        w.Write([]byte("hello world"))
      } else {
        body, _ := ioutil.ReadAll(r.Body)
        w.Write(body)
      }
    }
    

    La funzione helloHandler() imposta il tipo di contenuto su application/json. Risponde con "hello world" o il corpo eventualmente pubblicato.

Eseguire l'app

A questo punto la creazione del codice è stata completata, ma si devono eseguire alcune operazioni di configurazione per rendere operativo lo scenario. È necessario specificare dove si trova il file eseguibile, in modo che sia rilevabile dall'host di Funzioni, nonché configurare il routing e lo stato gestiti da questa app con i trigger HTTP e nessun altro tipo di associazione.

  1. Da un terminale eseguire go build server.go nella radice del progetto:

    go build server.go
    

    Questo passaggio crea un file eseguibile denominato server in macOS e Linux oppure oserver.exe in un sistema operativo Windows.

  2. Aprire il file host.json e trovare l'elemento defaultExecutablePath all'interno di customHandler. Specificare ./server in macOS e Linux oppure .\server.exe in un sistema operativo Windows.

  3. In customHandler aggiungere l'elemento enableForwardingHttpRequest e assegnargli il valore true. L'elemento customHandler avrà l'aspetto seguente:

    "customHandler": {
     "description": {
       "defaultExecutablePath": "./server",
       "workingDirectory": "",
       "arguments": []
     },
     "enableForwardingHttpRequest" : true
    }
    
  4. Da un terminale eseguire func start nella radice del progetto. Verrà così avviata l'app per le funzioni.

    func start
    

    Alla fine verrà visualizzato un output simile al seguente:

    Functions:
    
         hello: [GET,POST] http://localhost:7071/api/hello
    
  5. In un browser passare all'indirizzo http://localhost:7071/api/hello. Dovrebbe essere visibile l'output "hello world".

Si è così È stata sviluppata un'app serverless in Go.