Изобразяването на HTML е един от случаите на използване на Serverless, които опитах за първи път. Харесва ми идеята за:

  1. Една функция (без сървър)
  2. Рендиране на React компоненти (Рендиране от страната на сървъра)
  3. На HTTP крайна точка (състав на микроуслуги)
  4. Връщане на пълноценно приложение/страници. (Приложения за една страница)

Ползите от всеки един от отбелязаните коментари са добре документирани онлайн. От SSR, осигуряващ по-добро SEO и по-бързи отговори на мобилни устройства, до микроуслуги, определящи повечето от инфраструктурите на големите компании днес, до все по-сложни SPA, захранващи любимите ни приложения за социални мрежи и инструменти за сътрудничество онлайн, до удивителния потенциал на Serverless за спестяване на разходи и безкрайна мащабируемост.

Нека се опитаме да съберем прост пример за това как да ги постигнем всичките в един SPA, написан в React, внедрен в Google Cloud Functions.

Функция без сървър

Нека започнем с проста функция на Google Cloud.

$ mkdir my-serverless-app
$ cd my-serverless-app
$ npm init -y

Нека добавим малко код в index.js:

И нова стойност в раздела за скриптове на package.json:

"scripts": {
  "deploy": "gcloud beta functions deploy my-serverless-app-1_0_0 --entry-point handler --trigger-http --stage-bucket medium-post-functions --memory=2048MB"
},

След като поставим тези няколко части, можем просто да направим:

$ yarn deploy

И гледайте как нашият GCF се разгръща. Забележете, че използвах 2048Mb памет. (чувствайте се свободни да промените това по-късно). В този момент имаме HTTP крайна точка, която връща статично съдържание.

Rendered React от страна на сървъра

Създаването на друга реализация на SSR за React в този момент не е много продуктивно. Вече има много добри реализации на това. Плюс добър набор от библиотеки, за да ускорите разработката на React.

  • create-react-app (https://www.npmjs.com/package/create-react-app) Решава много проблеми при стартиране с React, но не и SSR.
  • nwb (https://www.npmjs.com/package/nwb) Подобно на create-react-app, но с поддръжка за Preact, Inferno, библиотека с компоненти и др.
  • react-cdk(https://github.com/storybooks/react-cdk) Хареса ми този, Storybooks е чудесен начин за създаване на библиотеки с компоненти с ръководства за стил на живо.
  • razzle (https://www.npmjs.com/package/razzle) Добра библиотека, прави SSR. +1 за използване на react-router v4.
  • следващ (https://www.npmjs.com/package/next) Вероятно най-завършената с функции React библиотека в момента. Дали SSR и неговата папка с примери е чисто JS злато. ;)

Така че ще използвам Nextjs. Най-добрият начин да научите как да го използвате е да посетите https://learnnextjs.com/ (направих го, отне ми ~20 минути, за да схвана основите). Продължаването на същото репо позволява първо да се добавят зависимости Nextjs.

$ yarn add react react-dom next
$ mkdir pages

И нека направим pages/index.js, който да служи като root на нашето приложение.

И малко допълнение към package.json:

{
  "scripts": {
    "dev": "next"
  }
}

Така че можем да направим сега:

$ yarn dev
DONE  Compiled successfully in 3775ms                                                                                                                             > Ready on http://localhost:3000

Отидете на http://localhost:3000и вижте нашето „Приложение“

Хубаво, но не много за сървърно визуализиране или облачни функции на Google. Трябва да изградим нашето приложение и да го обслужваме с помощта на манипулатор. Начинът, по който Nextjs препоръчва да направите това, е чрез създаване на персонализиран сървър (https://learnnextjs.com/basics/server-side-support-for-clean-urls/create-a-custom- сървър)

Тъй като нашият персонализиран сървър ще е необходим само за GCF, можем да го опростим до:

И също така добавете още един скрипт към package.json, за да изградите нашето приложение във вариант за внедряване. (По подразбиране създаденото приложение се съхранява в папка .next, проверете го)

{
  "scripts": {
    "build": "next build"
  }
}

Накрая:

$ yarn build
$ yarn deploy
....
httpsTrigger:
  url: https://us-central1-revelatio-165320.cloudfunctions.net/my-serverless-app-1_0_0
....

Можем да видим как нашето приложение за изобразяване на крайна точка реагира, ако отидем на: https://us-central1-revelatio-165320.cloudfunctions.net/my-serverless-app-1_0_0/

Обърнете внимание на крайната наклонена черта (/) в края на нашето извикване на крайна точка. Изглежда има няколко грешки от края на GCF и Nextjs. GCF приема, че маршрутът по подразбиране е празен низ, така че

https://us-central1-revelatio-165320.cloudfunctions.net/my-serverless-app-1_0_0
req.url === ''
https://us-central1-revelatio-165320.cloudfunctions.net/my-serverless-app-1_0_0/
req.url === '/'

И Nextjs се проваля, ако пътят е празен. Тази малка странност прекъсва крайната точка без наклонената черта в края. По-стабилна версия на нашата манипулираща функция може да бъде:

След повторно разполагане можем безопасно да осъществим достъп до нашата крайна точка HTTP без наклонената черта в края. FTW за рендиране от страна на сървъра.

Състав на микроуслуги

Всичко наред от страна на SSR. Но нашето приложение е фатално повредено от страна на клиента.

Ресурсите на нашето приложение не могат да бъдат изтеглени от GCF. Тези ресурси включват основно всички активи на приложението, като Javascript пакети, CSS и изображения (ако има такива). Nextjs използва абсолютни маршрути за извличане на активи и обработка на маршрутизирането. Трябва да обслужваме нашето приложение от основния корен на домейна или /.

Лесен начин да направите това може да бъде използването на NGINX:

http {
  upstream app_server {
    server us-central1-revelatio-165320.cloudfunctions.net;
  }
  server {
    listen       80;
    server_name  www.mi-app.com;
location / {
      proxy_pass   https://app_server/my-serverless-app-1_0_0;
      proxy_redirect off;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }
  }
}

NGINX е добър, ДОБЪР софтуер. Но IMHO истинският подход без сървър трябва да струва нула (cero) поддръжката на сървъра. И така, нека изберем друг доставчик, в този случай Fastly (https://www.fastly.com/)

На Fastly можем да създадем услуга:

  1. Задайте наш собствен домейн на приложението.
  2. Настройте Host да бъде нашия домейн на облачна функция, включително поддомейн. (Напр.: us-central1-revelatio-165320.cloudfunctions.net)
  3. Активирайте TLS и използвайте порт 443
  4. Име на хост на сертификат и име на хост на SNI същата стойност като #2
  5. Замяна на хост, зададен като #2
  6. Създайте правило за заглавка, за да трансформирате свойството req.url от заявката и пренапишете всички URL адреси от /* в /my-serverless-app-1_0_0/* (Тип: Заявка/Regex, Дестинация: url, източник: req.url, регулярен израз: ^(.*)$, заместване: /my-serverless-app- 1_0_0\1)

Разбира се, Fastly изисква да добавите CNAME регистър към DNS на вашия домейн, за да работи правилно.

След като всички тези настройки са на мястото си (отне ми 6 версии, за да го направя правилно), можете да разположите приложението си на GCF, насочено през много ефективен кеш и глобален CDN.

Други облачни функции на Google, като API бекенда, могат да бъдат внедрени с помощта на същия подход, по различни маршрути, разбира се. /api/v1 или /api/graphql.

(Проверете как да направите прост бекенд на mongoDB на GCF https://medium.com/google-cloud/creating-a-mongodb-crud-backend-on-google-cloud-functions-88bb5c1cef77)

Приложения за една страница

Е, на този етап този пост става твърде дълъг. Така че отидете на https://learnnextjs.com и https://github.com/zeit/next.js/tree/v3-beta/examples и създайте страхотни приложения.

Редактиране 1: Променен е малко примерът за NGINX нагоре по веригата. Не съм тествал напълно този подход, моята препоръка е да използвате Kong API Gateway (https://getkong.org).