IBM Cloud Docs
Desarrollo de una aplicación web

Desarrollo de una aplicación web

Esta guía de aprendizaje le muestra cómo crear una galería de imágenes simple utilizando IBM Cloud® Object Storage, reuniendo muchos conceptos y prácticas diferentes clave para el desarrollo web.

De principio a fin, la creación de una aplicación web cubre un montón de conceptos diferentes y es una buena forma de comenzar a conocer las prestaciones de IBM Cloud Object Storage. La aplicación utiliza IBM Cloud Object Storage para el almacenamiento en una aplicación Node.js que permite a un usuario cargar y ver archivos de imagen JPEG.

El caso de ejemplo

El escenario de esta guía de aprendizaje implica muchas partes móviles:

  • Un servidor web para alojar la aplicación web
  • Uso de la línea de comandos
  • Una instancia de almacenamiento para las imágenes en la galería
  • Un sistema de control de versiones integrado en la entrega continua
  • Enlaces de aplicación del lado del cliente en scripts y marcación
  • Imágenes para cargar y visualizar

Y si usted está buscando todo eso en un paquete, este tutorial proporcionará un completo, de principio a fin, ejemplo para usted. Sin embargo, esta instrucción sólo puede dejar temporalmente a un lado los principios de seguridad y código seguro. Las aplicaciones web realmente puestas en producción requieren una seguridad adecuada, o no serán adecuadas para posibles visitantes.

Antes de empezar

Asegúrese de que tiene lo que necesita para iniciar:

  • Una cuenta para IBM Cloud Platform
  • Docker, como parte de IBM Cloud Developer Tools
  • Node.js
  • Git (escritorio y línea de comandos)

Mediante la línea de mandatos

Empezaremos por abrir una herramienta bien conocida para los desarrolladores experimentados, y un nuevo mejor amigo para aquellos que acaban de empezar: la línea de mandatos. Para muchos, la interfaz gráfica de usuario (GUI) ha relegado la interfaz de línea de mandatos del sistema a un estado de segunda clase. Pero ahora, es el momento de traerlo de vuelta (aunque la GUI no va a desaparecer pronto, especialmente cuando necesita navegar por la web para descargar instrucciones para el conjunto de herramientas de línea de comandos).

Abra un shell y cree un directorio. Cambia tu propio directorio de referencia por el nuevo que has creado. Cuando se crea, la aplicación tiene su propio subdirectorio con el código de inicio y la configuración necesaria para empezar a funcionar.

Deje la línea de mandatos y vuelva al navegador para poder seguir las instrucciones para instalar las herramientas de desarrollador deIBM Cloud Platform en el enlace. Developer Tools ofrecen un enfoque extensible y repetible para crear e implantar aplicaciones en la nube.

Instalación de Docker

El uso de contenedores, como Docker, acelera el desarrollo y facilita las pruebas y da soporte al despliegue automatizado. Un contenedor es una estructura ligera que no necesita un sistema operativo, sólo su código y configuración para todo, desde dependencias hasta ajustes.

Docker se instala como parte de Developer Toolsy lo necesita. Su trabajo tiene lugar sobre todo en segundo plano dentro de unas rutinas que andamian tu nueva app. Docker debe estar en ejecución para que funcionen los mandatos de compilación. Cree una cuenta Docker en línea en Docker Hub, ejecute la aplicación Docker e inicie sesión.

Instalación de Node.js

La aplicación que construyes utiliza Node.JS como motor del lado del servidor para ejecutar el código JavaScript de esta aplicación web. Para utilizar el Gestor de Paquetes Node (npm) para gestionar las dependencias de tu aplicación, debes instalar Node localmente. Además, una instalación local de Node simplifica las pruebas, acelerando el desarrollo.

Antes de empezar, puede considerar un gestor de versiones, como Node Version Manager, o nvm, para instalar Node. Un gestor de versiones reduce la complejidad de gestionar distintas versiones de Node.js.

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash

...o ' wget (sólo es necesario uno, pero no ambos; utilice el que esté disponible en su sistema):

wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash

O, para Windows, puede utilizar ' nvm ' para Windows con los instaladores y el código fuente en el enlace.

Utilizando nvm, instale Node.

nvm install v6.17.1

Sea cual sea el enfoque que utilice después de instalar Node.js y npm (incluido con Node) en el sistema, ¡felicite por un trabajo bien iniciado!

Instalación de Git

Probablemente ya esté familiarizado con Git, ya que es el sistema de versiones de código fuente más utilizado. Utilizará Git más adelante cuando cree una cadena de herramientas de despliegue continuo (CD) en la plataforma IBM Cloud Para la entrega y el despliegue continuos. Si no tienes una cuenta de " GitHub ", crea una cuenta personal pública y gratuita en el sitio web de " GitHub "; si no, no dudes en conectarte con cualquier otra cuenta que tengas.

Debe generar y cargar claves SSH en el perfil de GitHub para obtener acceso seguro a GitHub desde la línea de mandatos. Sin embargo, hacerlo ahora proporciona una buena práctica, ya que repite los pasos para la instancia de GitHub utilizada para IBM Cloud Platform más tarde.

Por ahora, descargue GitHub Desktop y ejecute el instalador. Cuando finalice el instalador, inicie sesión en GitHub con su cuenta.

Especifique un nombre y un correo electrónico (esto se muestra públicamente) para las confirmaciones en el repositorio. Una vez que la aplicación está enlazada a la cuenta, es posible que se le solicite que verifique la conexión de la aplicación a través de la cuenta de GitHub en línea.

'GitHub Ventana de inicio de sesión en el escritorio
github_desktop_setup

Creación de la app de inicio Node.js

Para empezar a desarrollar su aplicación localmente, inicie sesión en la Plataforma IBM Cloud Directamente desde la línea de comandos, como se muestra en el ejemplo. Puede especificar parámetros opcionales, como la organización con la opción -o y el espacio con la opción -s. Si utiliza una cuenta federada, utilice " --sso.

ibmcloud login

Escriba el mandato tal como se muestra para descargar e instalar la extensión de CLI utilizada en esta guía de aprendizaje.

ibmcloud cf install

Al iniciar la sesión, es posible que se le solicite que elija una región. Para este ejercicio, seleccione us-south como región, ya que se utiliza la misma opción para crear una cadena de herramientas de CD más adelante en esta guía de aprendizaje.

A continuación, establezca el punto final (si todavía no se ha establecido). Otros puntos finales son posibles y pueden ser preferibles para su uso en producción. Por ahora, utilice el código como se muestra, si es apropiado para su cuenta.

ibmcloud api cloud.ibm.com

A continuación, cree una aplicación web. El espacio de dev es una opción predeterminada para su organización, pero es posible que prefiera crear otros para aislar diferentes esfuerzos. Por ejemplo, mantener "finanzas" separadas de "desarrollo".

ibmcloud dev create

Con ese comando, te hacen una serie de preguntas. Puede retroceder en muchos puntos del proceso, por lo que si se siente perdido puede empezar de nuevo suprimiendo el directorio existente y creando un nuevo directorio. Incluso cuando cree la aplicación en la línea de mandatos, seguirá viendo los resultados en la consola de IBM Cloud.

Tenga en cuenta la opción para crear una aplicación web. Ese es el que quieres.

===============================================================================
Select an application type:

 1. Backend Service / Web App
 2. Mobile App
-------------------------
 0. Exit

===============================================================================
? Enter selection number:> 1

Se proporcionan varias opciones, pero desea 'Node'. Escriba '4' y pulse Intro.

===============================================================================
Select a language:

 1. Go
 2. Java - MicroProfile / Java EE
 3. Java - Spring
 4. Node
 5. Python - Django
 6. Python - Flask
 7. Swift
-------------------------
 0. Return to the previous selection

===============================================================================
? Enter selection number:> 4

Después de realizar la selección para el lenguaje de programación y la infraestructura, la siguiente selección tendrá tantas opciones, es posible que se desplace más allá del servicio deseado. Como puede ver en el ejemplo, desea utilizar una aplicación web Node.js simple con Express.js. Escriba '3' y pulse Intro.

===============================================================================
Select a Starter Kit:

APPSERVICE
-------------------------------------------------------------------------------

 1. Node-RED - A starter to run the Node-RED open-source project on
    IBM Cloud.

 2. Node.js + Cloudant - A web application with Node.js and Cloudant

 3. Node.js Express App - Start building your next Node.js Express
    app on IBM Cloud.


WATSON
-------------------------------------------------------------------------------

 4. Natural Language Understanding Node.js App - Use Watson Natural
    Language Understanding to analyze text to help you understand its
    concepts, entities, keywords, sentiment, and more.

 5. Speech to Text Node.js App - React app using the Watson Speech to
    Text service to transform voice audio into written text.

 6. Text to Speech Node.js App - React app using the Watson Text to
    Speech service to transform text into audio.

 7. Visual Recognition Node.js App - React app using the Watson
    Visual Recognition service to analyze images for scenes, objects, text,
    and other subjects.

-------------------------
 0. Return to the previous selection

===============================================================================
? Enter selection number:> 3

La opción más difícil para los desarrolladores en todas partes sigue siendo necesaria: nombrar su app. Siga el ejemplo y escriba webapplication y, a continuación, pulse Intro.

? Enter a name for your application> webapplication

Después, puedes añadir tantos servicios, como almacenes de datos o funciones de cálculo, como necesites o quieras a través de la consola web. Sin embargo, escriba ' n' para no cuando se le pregunte si desea añadir servicios ahora. Además, si todavía no ha establecido un grupo de recursos, es posible que se le solicite en este momento. Puede saltarse esto escribiendo ' n' en esta solicitud.

Using the resource group Default (default) of your account

? Do you want to select a service to add to this application? [Y/n]> n

Una forma de gestionar una aplicación en contenedores es con software de orquestación, como Kubernetes, que es un estándar de facto en el desarrollo.

Escriba '4' y pulse enter para utilizarIBM DevOps' para integrar el DC en el ciclo de vida de su proyecto.

===============================================================================
Select from the following DevOps toolchain and target runtime environment
options:

 1. IBM DevOps, deploy to Knative-based Kubernetes containers
 2. IBM DevOps, deploy to Helm-based Kubernetes containers
 3. IBM DevOps, deploy to Helm-based Red Hat OpenShift containers
 4. No DevOps, with manual deployment

===============================================================================
? Enter selection number:> 4

Debe elegir una región para la cadena de herramientas de CD de despliegue automatizado. Seleccione la opción que hace referencia a la misma región que la elegida anteriormente, '5'.

--------------------------------------------------------------------------------
Select a region for your toolchain from the following options:
--------------------------------------------------------------------------------
 1. eu-de (Frankfurt)
 2. eu-gb (London)
 3. jp-tok
 4. us-east (Washington DC)
 5. us-south (Dallas)
--------------------------------------------------------------------------------
 0. Return to the previous selection
--------------------------------------------------------------------------------
? Enter selection number:> 5

La generación de una nueva aplicación nos recuerda que la cadena de herramientas utilizada para desplegar la app necesita alguna configuración adicional. Como se mencionó anteriormente, subir su clave pública a GitHub (en la instancia CD Toolchain en la Plataforma IBM Cloud Platform), es necesario para entregar la aplicación desplegada utilizando GitHub.

Note: For successful connection to the DevOps toolchain, this machine
must be configured for SSH access to your IBM Cloud GitLab account at
https://git.cloud.ibm.com/profile/keys in order to download the
application code.

Otras indicaciones confirman el nombre de la aplicación y de la cadena de herramientas que ha definido anteriormente. El ejemplo muestra cómo puede modificar los nombres del host y de la cadena de herramientas, si lo desea. El nombre de host debe ser exclusivo para el punto final de servicio de la aplicación, pero a menos que se produzca un conflicto, simplemente puede pulsar Volver cuando se le solicite la confirmación.

The DevOps toolchain for this app will be: webapplication
? Press [Enter] to accept this, or enter a new value now>


The hostname for this app will be: webapplication
? Press [Enter] to accept this, or enter a new value now>

The app webapplication has been created in IBM Cloud.

DevOps toolchain created at
https://cloud.ibm.com/devops/toolchains/6ffb568a-e48f-4e27-aed0-00ca931dde66?env_id=ibm:yp:us-south

Si copia y pega el enlace devuelto por el mandato ibmcloud dev create, también puede acceder a la cadena de herramientas de CD. Puedes acceder a ella desde la consola más tarde, por si no has captado el enlace. A continuación se proporciona más información, a medida que el proceso continúa creando entradas de aplicación en línea, así como un directorio con el código de ejemplo.

Cloning repository
https://git.cloud.ibm.com/Organization.Name/webapplication...
Cloning into 'webapplication'...
remote: Counting objects: 60, done.
remote: Compressing objects: 100% (54/54), done.
remote: Total 60 (delta 4), reused 0 (delta 0)
Receiving objects: 100% (60/60), 50.04 KiB | 1.52 MiB/s, done.
Resolving deltas: 100% (4/4), done.
OK

The app, webapplication, has been successfully saved into the
current directory.

Esta última afirmación significa que si visualizas tu directorio actual, ahora es visible un nuevo subdirectorio ' webapplication '. Este directorio contiene un andamio de la nueva aplicación Node.js. Sin embargo, aunque la receta puede estar presente, los propios ingredientes siguen envueltos en una imagen de Docker y deben combinarse. Docker se está ejecutando en su máquina local como consecuencia de la instalación, pero si necesita reiniciarlo hágalo. Si crea la nueva aplicación web sin Docker en ejecución, falla, pero no es el único error posible. Si tiene problemas, compruebe los mensajes de error resultantes, que pueden contener el enlace adecuado para ver los registros de resultados en el portal en línea de su cuenta de la plataforma IBM Cloud Cuenta de la plataforma.

ibmcloud dev build

Ahora que se ha creado la app, puede ejecutar el código localmente con el mandato run. Cuando termine, copie y pegue la URL proporcionada en la barra de direcciones de su navegador, normalmente, ' http://localhost:3000.

ibmcloud dev run

Ahora que la app se ha creado y definido, visualice la aplicación para confirmar que funciona. Si ves la imagen del marcador de posición como se muestra en la Figura 2, ¡bien hecho! Has creado una nueva aplicación web Node.js y estás listo para desplegarla en la nube.

¡Nueva aplicación ' Node.js '!
nodo inicial aplicación

Despliega la aplicación en la plataforma IBM Cloud Con el comando ' deploy ' (como se muestra en el ejemplo).

ibmcloud dev deploy

ibmcloud dev deploy vuelve a visualizar el URL basándose en el punto final regional y el nombre de host que ha especificado anteriormente. Puede ver enlaces a los registros almacenados en el portal en la plataforma IBM Cloud. El siguiente paso es visitar la nueva aplicación web en la nube.

Creación de la aplicación Galería web

Recordemos los requisitos previos necesarios para desarrollar una aplicación Node.js en IBM Cloud Plataforma. Ya ha creado la cuenta de IBM Cloud Platform y ha instalado Developer Tools, que ha instalado Docker. A continuación, ha instalado Node.js. El último elemento listado como requisito previo para esta guía de aprendizaje era Git, en el que se desmarca ahora.

Vamos a empezar los detalles específicos del trabajo en la galería de imágenes en Node.js. Por ahora, utilice GitHub Desktop para este escenario, pero también puede utilizar el cliente de línea de mandatos Git para completar las mismas tareas. Para empezar, clona una plantilla de inicio para tu nueva aplicación web.

Siga este proceso:

  1. Descargue el ejemplo aquí: download. Descargue la plantilla de su aplicación en su entorno de desarrollo local utilizando su navegador. En lugar de clonar la aplicación de ejemplo de la plataforma IBM Cloud Platform, utilice el comando del ejemplo para obtener la plantilla de inicio de la aplicación IBM Cloud Object Storage Web Gallery. Después de clonar el repositorio, encontrará la app de inicio en el directorio COS-WebGalleryStart. Abra una ventana CMD de Git y vaya al directorio en el que desea colar el repositorio Github. Una vez allí, utilice el mandato que se muestra en el primer ejemplo de esta guía de aprendizaje para empezar a añadir los nuevos archivos.

    curl images/image-gallery-tutorial.zip -o image-gallery-tutorial.zip
    
  2. Ejecute la aplicación localmente. Abra el terminal y cambie el directorio de trabajo a COS-WebGalleryStart directory. Tenga en cuenta las dependencias de Node.js que se listan en el archivo package.json. Descárguelos en su lugar utilizando el mandato que se muestra a continuación.

    npm install
    
  3. Ejecute la aplicación utilizando el comando que se muestra.

    npm start
    

    Abre un navegador y visualiza tu aplicación en la dirección y puerto que sale en la consola, ' http://localhost:3000.

    Para reiniciar la aplicación localmente, mata el proceso del nodo (Ctrl+C) para detenerlo y vuelve a utilizar " npm start ". El uso de nodemon en su lugar reinicia la aplicación cuando detecta un cambio y le ahorra tiempo. Instala ' nodemon ' globalmente así: npm install -g nodemon. Ejecútalo desde la línea de comandos en el directorio de tu app utilizando: nodemon, para iniciar tu app.

  4. Prepárese para preparar la app para el despliegue. Actualice el valor de la propiedad nombre de la aplicación en el archivo ' manifest.yml de COS-WebGallery, con el nombre que introdujo para su aplicación en IBM Cloud Platform y el resto de información como se muestra en el ejemplo, si es necesario. La aplicación manifest.yml se parece al ejemplo siguiente. Puedes personalizar el archivo ' package.json ' que se encuentra en el directorio raíz de tu aplicación con el nombre de tu aplicación y tu nombre como autor.

    applications:
    - path: .
      memory: 256M
      instances: 1
      domain: us-south.cf.appdomain.cloud
      name: webapplication
      host: webapplication
      disk_quota: 1024M
      random-route: true
    

    Ahora es el momento en el que puede que necesites configurar claves SSH para enviar código de forma interactiva a tu origen remoto. Si establece una frase de contraseña para su clave SSH, se le pedirá que introduzca este código cada vez que envíe sus cambios al origen remoto de su repositorio.

  5. Elimine y sustituya el contenido de su directorio ' webapplication ' por el contenido del directorio que ha modificado, ' COS-WebGalleryStart. Utilizando sus conocimientos adquiridos sobre Git, añada los archivos que se han suprimido y añadido al repositorio con la CLI o con Github Desktop. A continuación, envíe por push los cambios al origen del repositorio. En el futuro, podrás realizar cambios en tu aplicación web basada en la nube simplemente enviando los cambios a Git. La cadena de herramientas de CD reiniciará automáticamente el proceso del servidor después de clonar sus cambios y almacenarlos en el servidor.

En esencia, has recodificado tu aplicación, así que repite el proceso de compilación. Pero esta vez utiliza el nuevo código de la Galería de imágenes.

Despliegue de la app en IBM Cloud Platform.

Para obtener la app de inicio con sus cambios en IBM Cloud Platform, despliéguela utilizando las Developer Tools repitiendo los mismos pasos que ha realizado anteriormente.

  1. Si aún no lo ha hecho, o si ha reiniciado o cerrado la sesión, inicie sesión en IBM Cloud Platform utilizando el comando ' login '.

    ibmcloud login
    
  2. Establezca el punto final de API para su región utilizando el mandato api.

    ibmcloud api cloud.ibm.com
    
  3. Construya la aplicación para la entrega de esa aplicación con el comando build (como en el ejemplo).

    ibmcloud dev build
    
    1. Ahora vamos a probar la aplicación localmente. Esto le permite ejecutar el mismo código localmente con el mandato run.
    ibmcloud dev run
    
  4. Despliegue la app en IBM Cloud Platform con el mandato deploy.

    ibmcloud dev deploy
    

    El código muestra la secuencia de comandos que se utilizan en este ejemplo para construir, probar y desplegar la aplicación web inicial.

    ibmcloud login --sso
    ibmcloud api cloud.ibm.com
    ibmcloud target --cf
    ibmcloud dev enable
    ibmcloud dev build
    ibmcloud dev run
    ibmcloud dev deploy
    

    Cuando finaliza el proceso, la plataforma IBM Cloud informa de que la aplicación se ha cargado, desplegado e iniciado correctamente. Si también ha iniciado sesión en la consola web de la plataforma IBM Cloud Platform, también se le notificará el estado de su aplicación. Pero, lo que es más importante, puede verificar que la app se ha desplegado visitando el URL de la app que muestra IBM Cloud Platform con un navegador o desde la consola web pulsando el botón Ver app.

    Pruebe la app. El cambio visible entre la plantilla de app predeterminada que se desplegó durante la creación y la app de inicio mostrada demuestra que el despliegue de la app en IBM Cloud Platform se ha realizado correctamente.

    '

    ' Resultados de la visualización de su aplicación desplegada.
    ' '

Creación de una rama de Git

Ahora, tiene que crear una rama para el entorno de desarrollo local que se utilizará para la etapa de creación del conducto de entrega de IBM Cloud Platform:

  1. Si utilizas GitHub Desktop, haz clic en el icono de la rama; se te pedirá que introduzcas un nombre para la rama. Este ejemplo utiliza ' local-dev como nombre.

    Use GitHub Desktop to create a local dev branch

  2. Después de crear la rama, GitHub compara los archivos locales en la rama Local-dev con los archivos del repositorio en la rama por defecto e informa de Sin cambios locales. Ahora puede pulsar Publicar para añadir la rama que ha creado en el repositorio local al repositorio de GitHub (tal como se muestra en la Figura 5).

    Publish your git branch to your repo's remote origin

Ahora que la rama Local-dev está publicada en el repositorio de GitHub de tu cadena de herramientas, la etapa de compilación de tu IBM Cloud Platform Delivery Pipeline se activará seguida de la etapa de despliegue cada vez que envíes un commit a ella Platform Delivery Pipeline se activará seguida de la etapa de despliegue cada vez que envíe una confirmación a la misma. No es necesario desplegar la aplicación desde la CLI, ya que el despliegue se ha integrado directamente en su flujo de trabajo.

Configuración de las credenciales de almacenamiento

Tiene que configurar las credenciales de Object Storage para la aplicación web, así como un 'grupo' donde se almacenarán y se recuperarán las imágenes. La clave API que creará necesitará Object Storage Credenciales HMAC, tal y como se definen en sus credenciales de servicio. Es posible que reconozca los términos " access_key_id y " secret_access_key ", ya que podría tener una cuenta AWS y utilizar un archivo de credenciales que ya tiene entradas " aws_access_key_id y " aws_secret_access_key.

Cuando haya creado una clave de API, la haya descargado y la haya copiado en las credenciales de HMAC, siga los pasos siguientes:

  1. En el entorno de desarrollo local, coloque las credenciales en la vía de acceso de Windows %USERPROFILE%\\.aws\\credentials. Para los usuarios de Mac/Linux, las credenciales deben ir a ~/.aws/credentials). El ejemplo muestra el contenido de un archivo de credenciales típico.

    [default]
    aws_access_key_id = {access_key_id}
    aws_secret_access_key = {secret_access_key}
    
  2. En la página web de la aplicación que ha creado mediante el comando CLI en la plataforma IBM Cloud Platform, define las credenciales necesarias como variables de entorno según las mejores prácticas de desarrollo iniciando sesión en IBM Cloud Platform y selecciona tu aplicación, 'code1' Y seleccione su aplicación " webapplication. En las pestañas, haga clic en Tiempo de ejecución.

  3. En la ventana Tiempo de ejecución, haga clic en Variables de entorno al principio de la página y desplácese hasta la sección Definidas por el usuario, que le permite añadir las variables.

  4. Añade dos variables: una con el valor de tu ' access_key_id, utilizando ' AWS_ACCESS_KEY_ID como nombre de la clave, y otra con el valor de tu clave de acceso secreta, denominada ' AWS_SECRET_ACCESS_KEY. Estas variables y sus respectivos valores son lo que utiliza la app para autenticarse en la instancia de Object Storage cuando se ejecuta en IBM Cloud Platform (consulte la Figura 6). Cuando termine con las entradas, pulse Guardar y IBM Cloud Platform reiniciará automáticamente la app.

    Runtime Environment Variables defined for your app

A continuación, en el portal de Object Storage correspondiente a su instancia de servicio, añada un grupo que contendrá las imágenes. Este escenario utiliza el cubo denominado ' web-images.

Personalice la aplicación web de Node.js IBM Cloud Object Storage Image Gallery

Dado que en este ejemplo se utiliza una arquitectura MVC, el ajuste de la estructura de directorios dentro del proyecto para que refleje esta arquitectura resulta tanto práctico como recomendado. La estructura de directorios tiene un directorio views para contener las plantillas de vistas EJS, un directorio routes para contener las rutas express, y un directorio ' controllers ' como lugar para poner la lógica del controlador. Coloque estos elementos en un directorio fuente principal denominado " src (véase la figura 7).

Estructura del código fuente de tu aplicación
Estructura del directorio

Sugerencia: el repositorio que ha clonado anteriormente contiene un directorio denominado COS-WebGalleryEnd. Para seguir estos pasos le ayudará visualizar el código de origen de la aplicación completada en el editor que desee. Esta es la versión de tu ' webapplication ' que es confirmada y desplegada en la Plataforma ' IBM Cloud ' cuando completes este tutorial.

Diseño de la app

Estas son las dos tareas principales que un usuario debe poder realizar con la aplicación web sencilla de galería de imágenes:

  • Cargar imágenes desde un navegador web en un grupo de Object Storage.
  • Ver las imágenes del grupo de Object Storage en un navegador web.

En los pasos siguientes se describe cómo realizar estas dos funciones de demostración; no se trata de crear una app completamente desarrollada lista para producción. Desplegar esta guía de aprendizaje y dejarla expuesta y en ejecución significa que cualquiera que encuentre la app puede realizar las mismas acciones: cargar archivos en el grupo de IBM Cloud Object Storage y ver las imágenes JPEG que hay ahí en su navegador.

Desarrollo de la app

En el archivo ' package.json ', dentro del objeto scripts, se ve cómo se define "start". Este archivo es lo que utiliza IBM Cloud Platform para indicar al nodo que ejecute app.js cada vez que se inicie la app. Utilízalo también cuando pruebes la aplicación localmente. Mira el archivo principal de la aplicación, que se llama ' app.js. Este es el código que le dijiste a Node.js que procesara primero cuando iniciaras tu aplicación con el comando ' npm start (o ' nodemon).

{
    "scripts": {
      "start": "node app.js"
    }
}

Nuestro archivo app.js utiliza el nodo para cargar los módulos necesarios para empezar. La infraestructura Express crea la app como un singleton llamado simplemente app. El ejemplo termina (omitiendo la mayor parte del código por ahora) diciéndole a la aplicación que escuche en el puerto asignado y en una propiedad de entorno, o 3000 por defecto. Cuando se inicia con éxito, imprime un mensaje con la URL del servidor en la consola.

var express = require('express');
var cfenv = require('cfenv');
var bodyParser = require('body-parser');
var app = express();
//...

// start server on the specified port and binding host
var port = process.env.PORT || 3000;
app.listen(port, function() {
    console.log("To view your app, open this link in your browser: http://localhost:" + port);
});
//...

Vamos a ver cómo definir una ruta y vistas. La primera línea de código le dice al framework Express que utilice el directorio público para servir tus archivos estáticos, que incluyen cualquier imagen estática y hojas de estilo que utilices. Las líneas que siguen indican a la aplicación dónde encontrar las plantillas para tus vistas en el directorio ' src/views ', y configuran tu motor de vistas para que sea EJS. Además, el framework utiliza el middleware body-parser para exponer los datos de la solicitud entrante a la aplicación como JSON. En las últimas líneas del ejemplo, la aplicación express responde a todas las peticiones GET entrantes a la URL de tu aplicación mostrando la plantilla de vista " index.ejs.

//...
// serve the files out of ./public as your main files
app.use(express.static('public'));
app.set('views', './src/views');
app.set('view engine', 'ejs');
app.use(bodyParser.json());

var title = 'COS Image Gallery Web Application';
// Serve index.ejs
app.get('/', function (req, res) {
  res.render('index', {status: '', title: title});
});

//...

En la figura siguiente se muestra la plantilla de vista de índice cuando se representa y se envía al navegador. Si está utilizando,nodemon es posible que haya observado que el navegador se ha renovado al guardar los cambios.

Your updated web app by using templates and views for displays

Nuestras plantillas de vista comparten código HTML entre las etiquetas <head>...</head>;, por lo que lo ha colocado en una plantilla de inclusión separada. Esta plantilla (head-inc.ejs) contiene un scriptlet (un enlace para una variable JavaScript ) para el título de la página en la línea 1. La variable ' title ' se establece en ' app.js, y se pasa como datos para su plantilla de vista en la línea debajo de eso. De lo contrario, simplemente estará utilizando algunas direcciones CDN para extraer ' Bootstrap CSS, ' Bootstrap JavaScript y ' JQuery. Por último, añada un archivo styles.css estático personalizado desde el directorio pubic/stylesheets.

<title><%=title%></title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
      integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
      crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.1.1.min.js"
        integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
        crossorigin="anonymous">
</script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
        integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
        crossorigin="anonymous">
</script>

<link rel="stylesheet" href="stylesheets/style.css">

El cuerpo de la vista de índice contiene tus pestañas de navegación con estilo bootstrap, y tu formulario de carga en un diseño básico que es proporcionado por los estilos CSS incluidos con bootstrap.

Considere estas dos especificaciones para su aplicación:

  • Establezca su método de formulario como ' POST y el tipo de codificación de datos de formulario como multipart/form-data en la línea 24. Para la acción del formulario, envía los datos de tu formulario a la app a la ruta de la app "/". Más tarde, haz un trabajo extra en la lógica de tu enrutador para manejar las peticiones ' POST ' a esa ruta.

  • Muestra al usuario información sobre el estado del intento de carga de archivos. Esta información se pasa a la vista en una variable llamada "estado" y se muestra después del formulario de carga.

<!DOCTYPE html>
<html>

<head>
    <%- include('head-inc'); %>
</head>

<body>
<ul class="nav nav-tabs">
    <li role="presentation" class="active"><a href="/">Home</a></li>
    <li role="presentation"><a href="/gallery">Gallery</a></li>
</ul>
<div class="container">
    <h2>Upload Image to IBM Cloud Object Storage</h2>
    <div class="row">
        <div class="col-md-12">
            <div class="container" style="margin-top: 20px;">
                <div class="row">

                    <div class="col-lg-8 col-md-8 well">

                        <p class="wellText">Upload your JPG image file here</p>

                        <form method="post" enctype="multipart/form-data" action="/">
                            <p><input class="wellText" type="file" size="100px" name="img-file" /></p>
                            <br/>
                            <p><input class="btn btn-danger" type="submit" value="Upload" /></p>
                        </form>

                        <br/>
                        <span class="notice"><%=status%></span>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
</body>

</html>

Tomemos un momento para volver a app.js. El ejemplo configura rutas Express para gestionar las peticiones adicionales que se realicen a tu aplicación. El código para estos métodos de enrutamiento se encuentra en dos archivos bajo el directorio ' ./src/routes en su proyecto:

  • imageUploadRoutes.js: Este archivo maneja lo que sucede cuando el usuario selecciona una imagen y hace clic en Cargar.

  • galleryRoutes.js: Este archivo gestiona las peticiones cuando el usuario pulsa la pestaña Galería para solicitar la vista ' imageGallery '.

//...
var imageUploadRoutes = require('./src/routes/imageUploadRoutes')(title);
var galleryRouter = require('./src/routes/galleryRoutes')(title);

app.use('/gallery', galleryRouter);
app.use('/', imageUploadRoutes);

//...

Carga de imágenes

Consulte el código de imageUploadRoutes.js. Debes crear una instancia de un nuevo enrutador exprés y nombrarlo ' imageUploadRoutes ' al principio. Más tarde, crea una función que devuelva ' imageUploadRoutes, y asígnala a una variable llamada ' router. Una vez completada, la función debe exportarse como módulo para que sea accesible al framework y a tu código principal en ' app.js. Separar su lógica de enrutamiento de la lógica de carga requiere un archivo de controlador llamado ' galleryController.js. Como esa lógica se dedica a procesar la petición entrante y proporcionar la respuesta adecuada, pon esa lógica en esa función y guárdala en el directorio ' ./src/controllers.

La instancia del Router del framework Express es donde su ' imageUploadRoutes ' está diseñado para enrutar las peticiones a la ruta raíz de la app ("/") cuando se utiliza el método HTTP ' POST '. Dentro del método ' post de tu ' imageUploadRoutes, usa middleware de los módulos ' multer y ' multer-s3 ' que es expuesto por el ' galleryController como ' upload. El middleware toma los datos y el archivo de su formulario de carga ' POST, los procesa, y ejecuta una función de callback. En la función callback, comprueba que obtienes un código de estado HTTP de ' 200, y que tenías al menos un fichero en tu objeto request para subir. Basándose en esas condiciones, establezca la respuesta en su variable ' status y renderice la plantilla de vista de índice con el nuevo estado.

var express = require('express');
var imageUploadRoutes = express.Router();
var status = '';

var router = function(title) {

    var galleryController =
        require('../controllers/galleryController')(title);

    imageUploadRoutes.route('/')
    	.post(
    		galleryController.upload.array('img-file', 1), function (req, res, next) {
                if (res.statusCode === 200 && req.files.length > 0) {
                    status = 'uploaded file successfully';
                }
                else {
                    status = 'upload failed';
                }
                res.render('index', {status: status, title: title});
            });

    return imageUploadRoutes;
};

module.exports = router;

En comparación, el código del " galleryRouter " es un modelo de simplicidad. Siga el mismo patrón que hizo con ' imageUploadRouter y requiera ' galleryController ' en la primera línea de la función, luego configure su ruta. La principal diferencia es que está enrutando peticiones HTTP de ' GET ' en lugar de ' POST, y enviando toda la salida en la respuesta de ' getGalleryImages, que está expuesta por el ' galleryController ' en la última línea del ejemplo.

var express = require('express');
var galleryRouter = express.Router();

var router = function(title) {

    var galleryController =
        require('../controllers/galleryController')(title);

    galleryRouter.route('/')
        .get(galleryController.getGalleryImages);

    return galleryRouter;
};
module.exports = router;

A continuación, mire el controlador de la galería.

Tenga en cuenta cómo ha configurado la carga de multer, que trunca parte del código que ignora por ahora. Necesita los módulos ' ibm-cos-sdk, ' multer y ' multer-s3. El código muestra cómo configurar un objeto S3 que apunta a un punto final de servidor Object Storage. Usted está estableciendo estáticamente valores como la dirección del punto final, la región y el cubo para simplificar, pero podrían ser fácilmente referenciados desde una variable de entorno o un archivo de configuración JSON.

Defina upload en imageUploadRouter creando una nueva instancia de multer con storage como única propiedad. Esta propiedad le dice al ' multer ' dónde enviar el archivo desde su ' multipart/form-data. Dado que la Plataforma IBM Cloud Platform utiliza una implementación de la API S3, configure el almacenamiento para que sea un objeto ' s3-multer '. Este objeto s3-multer contiene una propiedad s3 que se asigna al objeto s3. También hay una propiedad bucket que se asigna a la variable myBucket, a la que a su vez se le asigna un valor de web-images. El objeto ' s3-multer ' tiene ahora todos los datos necesarios para subir archivos a su cubo Object Storage cuando reciba datos del formulario de subida. El nombre (o clave) del objeto cargado es el nombre de archivo original.

Utilice una indicación de fecha y hora como parte del nombre de archivo para mantener la exclusividad del nombre de archivo.

var galleryController = function(title) {

    var aws = require('ibm-cos-sdk');
    var multer = require('multer');
    var multerS3 = require('multer-s3');

    var ep = new aws.Endpoint('s3.us-south.cloud-object-storage.appdomain.cloud');
    var s3 = new aws.S3({endpoint: ep, region: 'us-south-1'});
    var myBucket = 'web-images';

    var upload = multer({
        storage: multerS3({
            s3: s3,
            bucket: myBucket,
            acl: 'public-read',
            metadata: function (req, file, cb) {
                cb(null, {fieldName: file.fieldname});
            },
            key: function (req, file, cb) {
                console.log(file);
                cb(null, file.originalname);
            }
        })
    });

    var getGalleryImages = function (req, res) { /* ... shown below ... */ };

    return {
        getGalleryImages: getGalleryImages,
        upload: upload
    };
};

module.exports = galleryController;

Para realizar pruebas locales, una tarea útil consiste en imprimir el objeto de archivo en la consola, console.log(file). Realice una prueba local del formulario de carga y muestre la salida del registro de la consola del archivo.

{ fieldname: 'img-file',
originalname: 'Chrysanthemum.jpg',
encoding: '7bit',
mimetype: 'image/jpeg' }

Los comentarios de la devolución de llamada declaran que la aplicación ha "cargado el archivo correctamente" cuando se ha probado.

' ¡Éxito!
localtest1

Recuperación y visualización de imágenes

Recuerda que en ' app.js', la línea de código ' app.use('/gallery', galleryRouter); le dice al framework express que use ese router cuando se solicite la ruta ' /gallery. Ese direccionador utiliza galleryController.js, defina la función getGalleryImages, cuya firma ha visto anteriormente. Usando el mismo objeto ' s3 ' que configuraste para tu función de subida de imágenes, llama a la función que se llama ' listObjectsV2. Esta función devuelve los datos de índice que definen cada uno de los objetos de su cubo. Para mostrar imágenes dentro de HTML, necesita una URL de imagen para cada imagen JPEG en su cubo ' web-images ' para mostrar en su plantilla de vista. El cierre con el objeto de datos devuelto por ' listObjectsV2 ' contiene metadatos sobre cada objeto de su bucket.

El código recorre el ' bucketContents ' buscando cualquier clave de objeto que termine en ".jpg," y crea un parámetro para pasarlo a la función S3 ' getSignedUrl. Esta función devuelve una URL firmada para cualquier objeto cuando se proporciona el nombre y la clave del bucket del objeto. En la función callback, guarda cada URL en un array, y pásalo al método de respuesta HTTP Server ' res.render como valor a una propiedad llamada ' imageUrls.

//...

    var getGalleryImages = function (req, res) {
        var params = {Bucket: myBucket};
        var imageUrlList = [];

        s3.listObjectsV2(params, function (err, data) {
            if (data) {
                var bucketContents = data.Contents;
                for (var i = 0; i < bucketContents.length; i++) {
                    if (bucketContents[i].Key.search(/.jpg/i) > -1) {
                        var urlParams = {Bucket: myBucket, Key: bucketContents[i].Key};
                        s3.getSignedUrl('getObject', urlParams, function (err, url) {
                            imageUrlList.push(url);
                        });
                    }
                }
            }
            res.render('galleryView', {
                title: title,
                imageUrls: imageUrlList
            });
        });
    };

//...

El último ejemplo de código muestra el cuerpo de la plantilla galleryView con el código necesario para visualizar las imágenes. Obtenga la matriz imageUrls del método res.render() e itere sobre un par de etiquetas <div>...</div> anidadas. Cada uno envía una solicitud GET para la imagen cuando se solicita la ruta /gallery.

<!DOCTYPE html>
<html>

<head>
    <%- include('head-inc'); %>
</head>

<body>
    <ul class="nav nav-tabs">
        <li role="presentation"><a href="/">Home</a></li>
        <li role="presentation" class="active"><a href="/gallery">Gallery</a></li>
    </ul>
    <div class="container">
        <h2>IBM COS Image Gallery</h2>

        <div class="row">
            <% for (var i=0; i < imageUrls.length; i++) { %>
                <div class="col-md-4">
                    <div class="thumbnail">
                            <img src="<%=imageUrls[i]%>" alt="Lights" style="width:100%">
                    </div>
                </div>
            <% } %>
        </div>
    </div>
</body>

</html>

Pruebe la app localmente desde http://localhost:3000/gallery y vea la imagen.

Las imágenes subidas al cubo están en la pantalla
localtest2

Confirmación en Git

Ahora que las características básicas de la aplicación están funcionando, envíe el código a su repositorio local y, a continuación, envíelo a GitHub. Utilizando GitHub Desktop, haga clic en Cambios (ver Figura 11), escriba un resumen de los cambios en el campo Resumen y, a continuación, haga clic en Confirmar en Local-dev.

Cambios listos para confirmar en ' Git' '
Confirmar actualizaciones

Al pulsar sincronizar, la confirmación se envía a la rama local-dev remota. Esta acción inicia las etapas de compilación y despliegue en el Delivery Pipeline.

CD ' Delivery Pipeline '
' '

Próximos pasos

Ha ido de principio a fin y ha creado una galería de imágenes de aplicación web básica utilizando la plataforma IBM Cloud. Cada uno de los conceptos que ha cubierto en esta introducción básica se puede explorar más a fondo en IBM Cloud Object Storage.

¡Buena suerte!