Continúo promocionando mi enlace de referencia al proveedor de IaaS Exostate y presento el segundo artículo de mi campaña publicitaria. En el primer artículo, implementé y lancé la aplicación ' vue-storefront ' como un servidor separado, sin estar atado a ningún dato, enmascarando de manera tan absurda mi interés comercial en vender servicios de Exoscale. Mis intentos patéticos fueron exitosamente abiertos por un colega de aol-nnov y me llevaron a limpiar el agua. Bueno, la segunda etapa de mi campaña publicitaria no es diferente de la primera: la misma página con un error:

El frente ahora está vinculado al backend (' vue-storefront-api '), pero el mismo mensaje sombrío " Algo salió mal ... " en el navegador del cliente. Por lo tanto, después de descartar la falsa modestia, presenté mi enlace de referencia a kat y puse todo el disfraz debajo de kat: detalles de cómo combiné Vue Storefront con Vue Storefront API.
Propósito
En esta etapa, me propuse la tarea de levantar un backend mínimamente funcional y cerrar el frente.
Esquema
Para que quede un poco más claro, les doy una imagen que desarrollé en función del análisis de las configuraciones de la aplicación:

La vue-storefront
implementación vue-storefront
que cité en un artículo anterior . Por lo tanto, vue-storefront-api
, Elasticsearch y Redis deben plantearse. A juzgar por la dirección / puerto en configQL, vue-storefront-api
es responsable de GraphQL.
Ambiente de trabajo
Para esta etapa, también tenía una versión pequeña del servidor Linux Ubuntu 18.04 LTS de 64 bits (2x CPU de 2198 MHz, 2 GB de RAM, disco de 10 GB). Lo bueno de IaaS es la capacidad de comenzar una y otra vez desde cero, arrojando experimentos fallidos anteriores a la basura.
Primera etapa
Aquí está el script para repetir los pasos del primer paso:
Será necesario mirar hacia el despliegue automático de vue-storefront
, sin intervención humana. Pero por ahora, así, con vsf
.
Instalar Elasticsearch
# apt install openjdk-11-jre-headless -y # java -version openjdk version "11.0.4" 2019-07-16 OpenJDK Runtime Environment (build 11.0.4+11-post-Ubuntu-1ubuntu218.04.3) OpenJDK 64-Bit Server VM (build 11.0.4+11-post-Ubuntu-1ubuntu218.04.3, mixed mode, sharing) # apt-get install apt-transport-https # wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add - # add-apt-repository "deb https://artifacts.elastic.co/packages/7.x/apt stable main" # apt update # apt install elasticsearch -y
Antes de comenzar el servicio, debe cambiar la configuración de Elasticsearch para poder acceder al servicio desde el exterior (esto no es necesario, pero es más conveniente para mí):
$ sudo nano /etc/elasticsearch/elasticsearch.yml cluster.name: habr_demo node.name: exo01 path.data: /var/lib/elasticsearch path.logs: /var/log/elasticsearch network.host: 0.0.0.0 discovery.seed_hosts: []
Lanzamiento de servicio:
# service elasticsearch restart
Y comprobando su rendimiento:
$ curl -X GET "http://localhost:9200/?pretty" { "name" : "exo01", "cluster_name" : "habr_demo", "cluster_uuid" : "_na_", "version" : { "number" : "7.4.2", "build_flavor" : "default", "build_type" : "deb", "build_hash" : "2f90bbf7b93631e52bafb59b3b049cb44ec25e96", "build_date" : "2019-10-28T20:40:44.881551Z", "build_snapshot" : false, "lucene_version" : "8.2.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" }
Instalar Redis
# apt install redis-server -y
Al igual que Elasticsearch, configuro Redis para que sea accesible desde el exterior:
# nano /etc/redis/redis.conf bind 0.0.0.0 # service redis-server start
Comienzo el servicio y verifico su rendimiento:
# service redis-server start # redis-cli > set test "It's working!" > get test > exit
Instalar vue-storefront-api
$ cd ~ $ git clone https://github.com/DivanteLtd/vue-storefront-api.git
Vinculación del frente al backend
Configuración frontal
Las opciones de configuración frontal disponibles se pueden encontrar en ~/vue-storefront/config/default.json
. Anulé algunas opciones en ~/vue-storefront/config/local.json
:
{ "server": { "host": "0.0.0.0", "port": 3000 }, "redis": { "host": "194.182.181.149", "port": 6379, "db": 0 }, "graphql": { "host": "194.182.181.149", "port": 8080 }, "api": { "url": "http://194.182.181.149:8080" }, "elasticsearch": {} }
server.host|.port
: server.host|.port
un servidor nodejs que generará contenido para el frente a todas las direcciones IP disponibles en el puerto correspondiente.
redis
y graphql
: se unen a la dirección IP externa de mi servidor de prueba. No sé si el servidor de nodejs que emite el contenido usa esta configuración, o si esta configuración se usa en el lado del cliente en el navegador, así que puse la dirección externa.
api.uri
: aquí definitivamente debe registrar la dirección IP externa del servidor, porque en la etapa anterior, vi llamadas de API desde el navegador (aplicaciones PWA) en los registros de solicitud (pestaña Network
en la barra de herramientas). Esta es la dirección de puerto en la que se colgará el servidor nodejs de la aplicación vue-storefront-api
.
Configuración de backend
Las opciones de configuración disponibles también se pueden ver en ~/vue-storefront-api/config/default.json
. Estas son las opciones anuladas en ~/vue-storefront-api/config/local.json
:
{ "server": { "host": "0.0.0.0", "port": 8080 }, "elasticsearch": { "host": "localhost", "port": 9200 }, "redis": { "host": "localhost", "port": 6379 } }
server.host|.port
: server.host|.port
un servidor nodejs que proporcionará contenido para la API a todas las direcciones IP disponibles en el puerto correspondiente.
redis
y redis
se encuentran en el mismo host que el servidor API, por lo que solo repito los parámetros predeterminados.
Construcción de la aplicación
Frente
$ cd ~/vue-storefront $ yarn install $ yarn build
Backend
$ cd ~/vue-storefront-api $ yarn install $ yarn build
Iniciar y detener aplicaciones
$ cd ~/vue-storefront-api $ yarn start ... $ cd ~/vue-storefront $ yarn start ... [PM2][WARN] Applications server not running, starting... [PM2] App [server] launched (4 instances) ┌──────────┬────┬─────────┬──────┬────────┬─────────┬────────┬───────┬───────────┬────────┬──────────┐ │ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │ ├──────────┼────┼─────────┼──────┼────────┼─────────┼────────┼───────┼───────────┼────────┼──────────┤ │ api │ 0 │ fork │ 3690 │ online │ 0 │ 11s │ 0% │ 85.2 MB │ ubuntu │ disabled │ │ o2m │ 1 │ fork │ 3696 │ online │ 0 │ 11s │ 0% │ 48.4 MB │ ubuntu │ disabled │ │ server │ 2 │ cluster │ 3763 │ online │ 0 │ 0s │ 26.7% │ 66.9 MB │ ubuntu │ disabled │ │ server │ 3 │ cluster │ 3770 │ online │ 0 │ 0s │ 0% │ 68.1 MB │ ubuntu │ disabled │ │ server │ 4 │ cluster │ 3785 │ online │ 0 │ 0s │ 0% │ 40.9 MB │ ubuntu │ disabled │ │ server │ 5 │ cluster │ 3796 │ online │ 0 │ 0s │ 0% │ 40.9 MB │ ubuntu │ disabled │ └──────────┴────┴─────────┴──────┴────────┴─────────┴────────┴───────┴───────────┴────────┴──────────┘ Use `pm2 show <id|name>` to get more details about an app Done in 1.49s.
Parada:
$ pm2 stop all
Ver registros:
$ pm2 log
Conexión de la aplicación
Dirección de la aplicación: http : //194.182.181.149haps000/ Como resultado, tenemos un mensaje de error en el navegador al principio, pero en los registros del servidor API podemos grabar las llamadas del navegador a la API:
$ pm2 log 3|server | 2019-11-16 07:44:33: Error during render : / 3|server | 2019-11-16 07:44:33: Error: FetchError in request to ES: FetchError: invalid json response body at http://194.182.181.149:8080/api/catalog/vue_storefront_catalog/product/_search?_source_exclude=%2A.msrp_display_actual_price_type%2Crequired_options%2Cupdated_at%2Ccreated_at%2Cattribute_set_id%2Coptions_container%2Cmsrp_display_actual_price_type%2Chas_options%2Cstock.manage_stock%2Cstock.use_config_min_qty%2Cstock.use_config_notify_stock_qty%2Cstock.stock_id%2Cstock.use_config_backorders%2Cstock.use_config_enable_qty_inc%2Cstock.enable_qty_increments%2Cstock.use_config_manage_stock%2Cstock.use_config_min_sale_qty%2Cstock.notify_stock_qty%2Cstock.use_config_max_sale_qty%2Cstock.use_config_max_sale_qty%2Cstock.qty_increments%2Csmall_image%2Csgn%2C%2A.sgn&from=0&request=%7B%22query%22%3A%7B%22bool%22%3A%7B%22filter%22%3A%7B%22bool%22%3A%7B%22must%22%3A%5B%7B%22terms%22%3A%7B%22category.name.keyword%22%3A%5B%22Tees%22%5D%7D%7D%2C%7B%22terms%22%3A%7B%22visibility%22%3A%5B2%2C3%2C4%5D%7D%7D%2C%7B%22terms%22%3A%7B%22status%22%3A%5B0%2C1%5D%7D%7D%5D%7D%7D%7D%7D%7D&size=8&sort=created_at%3Adesc reason: Unexpected end of JSON input 3|server | at w (core/server-entry.ts:23:25) 3|server | at server-bundle.js:1:468554 3|server | at processTicksAndRejections (internal/process/task_queues.js:93:5) 3|server | 2019-11-16 07:44:33: whole request [/error]: 56ms 0|api | 2019-11-16 07:44:34: OPTIONS /api/cart/create?token= 204 1.320 ms - 0 0|api | 2019-11-16 07:44:34: POST /api/cart/create?token= 200 465.416 ms - 56 0|api | 2019-11-16 07:44:34: OPTIONS /api/cart/pull?token=&cartId=35bea3b7dcf8fb841187d69489fe8c51 204 0.239 ms - 0 0|api | 2019-11-16 07:44:34: GET /api/cart/pull?token=&cartId=35bea3b7dcf8fb841187d69489fe8c51 200 103.949 ms - 24
2Cattribute_set_id% 2Coptions_container% 2Cmsrp_display_actual_price_type% 2Chas_options% 2Cstock.manage_stock% 2Cstock.use_config_min_qty% 2Cstock.use_config_notify_stock_qty% 2Cstock.stock_id% 2Cstock.use_config_backorders% 2Cstock.use_config_enable_qty_inc% 2Cstock.enable_qty_increments% 2Cstock.use_config_manage_stock% 2Cstock $ pm2 log 3|server | 2019-11-16 07:44:33: Error during render : / 3|server | 2019-11-16 07:44:33: Error: FetchError in request to ES: FetchError: invalid json response body at http://194.182.181.149:8080/api/catalog/vue_storefront_catalog/product/_search?_source_exclude=%2A.msrp_display_actual_price_type%2Crequired_options%2Cupdated_at%2Ccreated_at%2Cattribute_set_id%2Coptions_container%2Cmsrp_display_actual_price_type%2Chas_options%2Cstock.manage_stock%2Cstock.use_config_min_qty%2Cstock.use_config_notify_stock_qty%2Cstock.stock_id%2Cstock.use_config_backorders%2Cstock.use_config_enable_qty_inc%2Cstock.enable_qty_increments%2Cstock.use_config_manage_stock%2Cstock.use_config_min_sale_qty%2Cstock.notify_stock_qty%2Cstock.use_config_max_sale_qty%2Cstock.use_config_max_sale_qty%2Cstock.qty_increments%2Csmall_image%2Csgn%2C%2A.sgn&from=0&request=%7B%22query%22%3A%7B%22bool%22%3A%7B%22filter%22%3A%7B%22bool%22%3A%7B%22must%22%3A%5B%7B%22terms%22%3A%7B%22category.name.keyword%22%3A%5B%22Tees%22%5D%7D%7D%2C%7B%22terms%22%3A%7B%22visibility%22%3A%5B2%2C3%2C4%5D%7D%7D%2C%7B%22terms%22%3A%7B%22status%22%3A%5B0%2C1%5D%7D%7D%5D%7D%7D%7D%7D%7D&size=8&sort=created_at%3Adesc reason: Unexpected end of JSON input 3|server | at w (core/server-entry.ts:23:25) 3|server | at server-bundle.js:1:468554 3|server | at processTicksAndRejections (internal/process/task_queues.js:93:5) 3|server | 2019-11-16 07:44:33: whole request [/error]: 56ms 0|api | 2019-11-16 07:44:34: OPTIONS /api/cart/create?token= 204 1.320 ms - 0 0|api | 2019-11-16 07:44:34: POST /api/cart/create?token= 200 465.416 ms - 56 0|api | 2019-11-16 07:44:34: OPTIONS /api/cart/pull?token=&cartId=35bea3b7dcf8fb841187d69489fe8c51 204 0.239 ms - 0 0|api | 2019-11-16 07:44:34: GET /api/cart/pull?token=&cartId=35bea3b7dcf8fb841187d69489fe8c51 200 103.949 ms - 24
2Cstock.qty_increments% 2Csmall_image% 2Csgn% 2C% 2A.sgn y desde = $ pm2 log 3|server | 2019-11-16 07:44:33: Error during render : / 3|server | 2019-11-16 07:44:33: Error: FetchError in request to ES: FetchError: invalid json response body at http://194.182.181.149:8080/api/catalog/vue_storefront_catalog/product/_search?_source_exclude=%2A.msrp_display_actual_price_type%2Crequired_options%2Cupdated_at%2Ccreated_at%2Cattribute_set_id%2Coptions_container%2Cmsrp_display_actual_price_type%2Chas_options%2Cstock.manage_stock%2Cstock.use_config_min_qty%2Cstock.use_config_notify_stock_qty%2Cstock.stock_id%2Cstock.use_config_backorders%2Cstock.use_config_enable_qty_inc%2Cstock.enable_qty_increments%2Cstock.use_config_manage_stock%2Cstock.use_config_min_sale_qty%2Cstock.notify_stock_qty%2Cstock.use_config_max_sale_qty%2Cstock.use_config_max_sale_qty%2Cstock.qty_increments%2Csmall_image%2Csgn%2C%2A.sgn&from=0&request=%7B%22query%22%3A%7B%22bool%22%3A%7B%22filter%22%3A%7B%22bool%22%3A%7B%22must%22%3A%5B%7B%22terms%22%3A%7B%22category.name.keyword%22%3A%5B%22Tees%22%5D%7D%7D%2C%7B%22terms%22%3A%7B%22visibility%22%3A%5B2%2C3%2C4%5D%7D%7D%2C%7B%22terms%22%3A%7B%22status%22%3A%5B0%2C1%5D%7D%7D%5D%7D%7D%7D%7D%7D&size=8&sort=created_at%3Adesc reason: Unexpected end of JSON input 3|server | at w (core/server-entry.ts:23:25) 3|server | at server-bundle.js:1:468554 3|server | at processTicksAndRejections (internal/process/task_queues.js:93:5) 3|server | 2019-11-16 07:44:33: whole request [/error]: 56ms 0|api | 2019-11-16 07:44:34: OPTIONS /api/cart/create?token= 204 1.320 ms - 0 0|api | 2019-11-16 07:44:34: POST /api/cart/create?token= 200 465.416 ms - 56 0|api | 2019-11-16 07:44:34: OPTIONS /api/cart/pull?token=&cartId=35bea3b7dcf8fb841187d69489fe8c51 204 0.239 ms - 0 0|api | 2019-11-16 07:44:34: GET /api/cart/pull?token=&cartId=35bea3b7dcf8fb841187d69489fe8c51 200 103.949 ms - 24
Conclusión
Gestionado para ir un paso más allá: Vue Storefront PWA se comunica con la API de Vue Storefront. A continuación, debe lidiar con el contenido del back-end. Qué datos se indexan en Elasticsearch, cómo llegan allí y cómo se recuperan.
Gracias por leer y hacer clic en mi enlace de referencia. Bueno, maldita sea, por el bien de ella, aquí se amontonó todo esto.