Aplicación web

Completado

Para usar un controlador personalizado, debe crear una aplicación web. Después de escribir la aplicación y compilarla, debe configurar el host de Azure Functions para que sepa cómo usarla. Lo exploraremos con detalle más adelante. En primer lugar, ¿cómo se compila una aplicación web en Go?

Compilación de una API de REST en Go

Para compilar una API de REST mediante Go, debe saber algunas cosas:

  • Importación de bibliotecas. Usará las bibliotecas fmt, log y net/http. Estas bibliotecas le ayudarán a administrar las rutas, controlar las solicitudes entrantes y gestionar el registro. Use la siguiente instrucción import:

    import (
       "fmt",
       "log",
       "net/http"
    )    
    
  • Configuración del enrutamiento. Las API de REST constan de divisiones lógicas denominadas rutas. Las rutas son direcciones que responden a un problema específico de la aplicación. Para configurar una ruta, llame al método HandleFunc() en la instancia de http y defina la ruta para responder a las solicitudes:

    http.HandleFunc("/", handleRoute)   
    

    En este caso, debe crear una función handleRoute que coincida con las solicitudes entrantes en la ruta "/".

  • Administración de solicitudes. Debe administrar las solicitudes entrantes y leer objetos como los parámetros de enrutador o consulta o un cuerpo publicado. A continuación, debe crear una respuesta. Una función que controla una solicitud puede tener este aspecto:

    func handleRequest(w: http:ResponseWriter, r: http.Request) {
        fmt.Fprintf(w, "My first REST API") 
    }
    

    El código devuelve el texto "Mi primera API de REST" a un cliente que realiza la llamada. El método Fprintf() toma dos argumentos: el flujo de respuesta y la cadena que se va a devolver.

  • Creación del servidor. Para poder escuchar las solicitudes, debe iniciar el servidor. También debe especificar un elemento al que se puedan enviar solicitudes. El código siguiente muestra cómo se crea el servidor:

    http.ListenAndServe(":3000", nil)
    

    El servidor ya está en marcha y puede escuchar las solicitudes en el puerto 3000.

Creación de una aplicación de Azure Functions

Antes de desarrollar una aplicación de Azure Functions, se recomienda lo siguiente:

Scaffolding de una aplicación de Functions mediante Visual Studio Code

Una vez instaladas todas las dependencias necesarias en el sistema, el siguiente paso es realizar el scaffolding de una aplicación. Cuando se le pregunte sobre el entorno de ejecución, elija Controlador personalizado.

Ahora se ha asegurado de que se generarán los archivos correctos. Al generar un proyecto de esta manera, debe seleccionar un tipo de desencadenador para la primera función. Los controladores personalizados funcionan con todos los desencadenadores y enlaces habituales.

Cuando termine de generar el proyecto, debe tener una aplicación con los siguientes archivos:

  • host.json
  • local.setting.json
  • proxies.json
  • function.json

El archivo function.json está en un directorio cuyo nombre se corresponde con el que asignó a la primera función. Usará este archivo para configurar la función.

Configuración del proyecto

Para que la aplicación funcione con primitivas HTTP, debe configurar algunas cosas:

  • Escuche un puerto de controlador personalizado. La aplicación debe escuchar un puerto específico. La variable FUNCTIONS_CUSTOMHANDLER_PORT contiene el valor que necesita. Puede buscar el valor del puerto mediante el código siguiente:

    customHandlerPort, exists := os.LookupEnv("FUNCTIONS_CUSTOMHANDLER_PORT")
    
  • Configure la ruta de acceso del archivo ejecutable predeterminada. Dado que está creando un archivo ejecutable, debe indicar al proyecto de aplicación de Functions dónde se encuentra.

    Busque el archivo function.json en la raíz del proyecto. En la sección customHandler, especifique defaultExecutablePath. En el ejemplo siguiente se muestra el aspecto que puede tener:

    "customHandler": {
       "defaultExecutablePath": "mygoapp.exe"
    }
    
  • Habilitación del reenvío de solicitudes. Al tratar con una función que usa un desencadenador HTTP, la intención es configurar la aplicación de forma ligeramente diferente a si tratara con otro tipo de desencadenador (como un desencadenador de cola).

    Una propiedad denominada enableForwardingHttpRequest. Cuando esta propiedad está habilitada, cambia el comportamiento del control de la solicitud de las maneras siguientes:

    • Copia de la solicitud original. La solicitud HTTP no contiene la carga de la solicitud de los controladores personalizados. En su lugar, el host de Functions invoca el controlador con una copia de la solicitud HTTP original.

    • La misma ruta de acceso que la solicitud original. El host de Functions invoca el controlador con la misma ruta de acceso que la solicitud original.

      Al definir una ruta y un controlador de ruta, debe ser específico en la manera de configurar el enrutamiento. Digamos que tiene el esquema de proyecto siguiente:

      hello/
        function.json   
      

      Los archivos del esquema se asignarán a una ruta /api/hello de forma predeterminada. En el código para configurar la ruta, debe especificar la ruta completa:

      mux.HandleFunc("/api/hello", helloHandler)
      

      Si no hubiera habilitado esta configuración, para otros tipos de desencadenadores y enlaces, especificar el código del enrutador como "/hello" habría sido suficiente.

    • Copia de la respuesta del controlador. El host de Functions devuelve una copia de la respuesta HTTP del controlador como respuesta a la solicitud original.

En el ejemplo anterior, el archivo ejecutable es mygoapp.exe. En el ejemplo se da por supuesto que está creando el archivo ejecutable a partir de un archivo denominado mygoapp.go, pero puede asignar al archivo de Go el nombre que desee. En Linux o macOS, el archivo ejecutable no tiene una extensión.

Compilar la aplicación

La compilación de la aplicación web en este momento no es muy diferente de la compilación de cualquier aplicación web mediante Go. Siempre que haya realizado la configuración descrita en la sección anterior, estará preparado.

Ahora debe realizar los pasos siguientes:

  1. Lea el puerto.
  2. Cree la instancia del servidor HTTP.
  3. Defina rutas y controladores de ruta.
  4. Inicie la escucha en el puerto.
customHandlerPort, exists := os.LookupEnv("FUNCTIONS_CUSTOMHANDLER_PORT")
if !exists {
   customHandlerPort = "8080"
} // 1)
mux := http.NewServeMux() // 2)
mux.HandleFunc("/order", orderHandler) // 3)
fmt.Println("Go server Listening on: ", customHandlerPort)
log.Fatal(http.ListenAndServe(":"+customHandlerPort, mux)) // 4)