Създайте React приложение с пълен стек с достъп до база данни за минути

TL;DR:В тази публикация ние създаваме пълно стеково React приложение от нулата с Infrastructure-Components. Взимаме някои потребителски данни и ги съхраняваме в база данни (DynamoDB) чрез интерфейс GraphQL. Ние също извличаме данните от базата данни и ги показваме. Ние покриваме два начина за работа с базата данни:

  1. С компонентите на React-Apollo (<Query/> и <Mutation/>)
  2. С куките на React-Apollo

Определете архитектурата на вашето приложение

Настроихме нашия проект с помощта на Infrastructure-Components. Тези React-компоненти ни позволяват да дефинираме нашата инфраструктурна архитектура като част от нашето React-приложение. Вече не се нуждаем от друга конфигурация като Webpack, Babel или Serverless.

Можем да се концентрираме върху функционалната част на нашето приложение. Това е: Как да работите с база данни в React.

„Инфраструктурни компоненти“ поддържат създаването на основни „приложения с една страница“, както и „ориентирани към услуги приложения за реакция“. Последните поддържат бекенд услуги и бази данни извън кутията. Тази публикацияосигурява настройката, която ще използваме в тази публикация. Но ние ще преминем през основните моменти и тук.

Базираните на Инфраструктурни компоненти проекти имат един компонент от най-високо ниво. Това определя архитектурата на вашето приложение. Подкомпонентите (децата) прецизират поведението на приложението и добавят функции.

За да създадем приложение с пълен стек, ние използваме <ServiceOrientedApp/>-компонента като компонент от най-високо ниво. Ние го експортираме по подразбиране в нашия файл с входна точка (src/index.tsx).

A <ServiceOrientedApp/> е интерактивно уеб приложение. Поддържа използването на маршрути, услуги и база данни.

  • <Route/> е страница от вашето приложение. работи като <Route/> в react-router. Можем да изобразим всичко от обикновен <div/> до страница, пълна с React компоненти. „Ето“ урок за това как да работите с маршрути.
  • <Service/> дефинира функция, която се изпълнява от страната на сървъра. Може да има един или много <Middleware/>-компоненти като деца. <Middleware/> работи като Express.js-middleware.
  • <DataLayer/> добавя NoSQL-база данни (DynamoDB) към вашето приложение.
  • <Envrionment/> създава време за изпълнение на вашето приложение, което ви позволява да го стартирате и внедрите.

Първи стъпки

Можете да настроите своя проект по три начина:

След като инсталирате зависимостите (изпълнете npm install, ако сте клонирали или изтеглили файловете), можете да изградите проекта с една команда:
npm run build. Тогава:

  • npm run {your-project-name} стартира вашето React-приложение локално (режим на гореща разработка, без бекенд и база данни). Режимът на гореща разработка е особено полезен по време на разработването на потребителския интерфейс. Това са всички визуални неща. В този режим промените в изходния код влизат в сила незабавно. Този режим обаче не стартира backend-services и базата данни.
  • npm run start-{your-env-name}стартира целия софтуерен стек локално. Той стартира потребителския интерфейс, услугите и базата данни. Но трябва да го рестартирате, когато промените своя изходен код.
    Забележка (1): Стартирането на базата данни в офлайн режим изисква Java 8 JDK. Ето как можете да инсталирате JDK.
    Забележка (2): локалната база данни изисква известно време, за да започне. В резултат на това първото запитване отнема доста време. Последващите заявки са по-бързи.

Настройте структурата на данните

Компонентът <DataLayer/> създава Amazon DynamoDB. Това е база данни ключ-стойност (NoSQL). Той приема <Entry/>-компоненти като деца. <Entry/> описва типа елементи във вашата база данни. Това е абстрактното описание на вашите данни. Не е пример. Екземпляр на <Entry/> е елемент.

<Entry/> указва имената на своите primaryKey и rangeKey. Той също така съдържа плосък Javascript обект като data-поле.

Да речем, че искаме да съхраняваме нашите публикувани статии в база данни. Следното <Entry/> описва структурата на article-елементите.

  • Ние определяме имена за нашите primaryKey и rangeKey. Можете да използвате всяко име, с изключение на някои ключови думи на DynamoDB, които можете да намерите тук. Списъкът е доста дълъг. Така че по-добре използвайте комбинирани думи, като articleid вместо id.
  • Елемент (известен още като отделен екземпляр на <Entry/>) трябва да предоставя стойности за primaryKey и за rangeKey. Тези стойности са задължителни. article-артикул трябва да има articleid и title.
  • Елемент може (по избор) да предостави стойности за ключовете в полето data. article-артикул може да има articlelink.
  • Комбинацията от primaryKey и rangeKey описва уникален елемент в базата данни. Не може да има второ article, което да има същото articleid и същото title. От гледна точка на базата данни, би било добре, ако две article имат едно и също articleid, когато щяха да имат различно title (или обратното).
  • Не трябва да има други <Entry/> със същите имена като primaryKey и rangeKey. Едно име може да съвпада, но не и двете. Не можем да имаме друг <Entry/> в нашата база данни с primaryKey="articleid” и rangeKey="title".

Да кажем, че искаме нашите статии да имат tags. tag е дума като „програмиране“, „реагиране“ или „javascript“. Той описва съдържанието на article. article може да има произволен брой tags. Но може да има всяко tag само веднъж.

Следният <Entry/> описва структурата на tag-елементите.

Помня. Комбинацията от primaryKey и rangeKey описва уникален елемент в базата данни. Следователно article може да има tag само веднъж. Но article може да има произволен брой tags. И различни article могат да имат едно и също tag.

Работа с данни

Стига с подготовката! Да работим с данните.

Следващите подраздели показват различни начини за това как можете да запазвате и заявявате данни. Те са равни от функционална гледна точка. Това означава, че имат същия резултат.

Можете да изберете този, който най-добре отговаря на поставената ви задача. Или просто използвате този, който ви харесва най-много.

Добавете статия

Започваме с празна база данни. Нека променим това, като добавим article.

Потребителският интерфейс на следния React-компонент е проста форма. Има две <input/> полета и <button/>.

Всеки <input/> се свързва с локалното състояние чрез React-hook. Това състояние съхранява въведените стойности в предния край (раздел на браузъра). Няма го, ако опресните страницата. Все още не се съхранява в базата данни.

<button/> задейства съхраняването на стойностите в базата данни. <button/> изпълнява функцията postMutation, която получава от компонента <Mutation/>.

<Mutation/>-компонентът прави цялата магия. Внасяме го от react-apollo. „Ето“ описанието на този компонент.

<Mutation/>-компонентът приема като свойства: mutation-query и незадължително context. Получаваме и двете от функцията setEntryMutation. Ние инжектираме тази функция в props на нашия компонент чрез „Компонента от по-висок порядък“ (HOC) withDataLayer.

Параметрите ни позволяват да опишем елемента, който искаме да добавим:

  • id уточнява <Entry/>. За да създадем article, ние предоставяме id на <ArticleEntry/>.
  • Javascript обект с данните на елемента. Това включва стойностите на primaryKey и rangeKey. Ключовете на този Javascript обект съвпадат с имената, които посочихме в <Entry/>.

В нашия пример ние вземаме стойностите на title и articlelink от <input/>s. Използваме UUID като articleid.

withDataLayer-HOC добавя две функции към props, които можем да подадем към <Mutation/>-компонента.

  • setEntryMutation (който използваме тук) съхранява елемент. Той добавя нов елемент, ако все още не съществува елемент с указаната комбинация от primaryKey и rangeKey. Той презаписва елемент, ако има същата комбинация от primaryKey и rangeKey.
  • deleteEntryMutation изтрива елемент от базата данни.

И двете функции приемат едни и същи параметри.

Показване на списък със статии

Сега нека покажем статиите, които сме съхранили в нашата база данни.

Използваме <Query/>-компонента, който импортираме от react-apollo. „Ето“ описанието на този компонент.

<Query/>-компонентът приема като свойства: query и незадължителен context.

withDataLayer-HOC предоставя следните функции на props, които можем да подадем към <Query/>-компонента.

  • getEntryQuery извлича един елемент. Трябва да посочим id на <Entry/> и стойностите на primaryKey и rangeKey на елемента.
  • getEntryListQuery извлича списък с елементи. Трябва да посочим id на <Entry/> и стойност на primaryKey или rangeKey. Връщаме всички артикули с посочената стойност.
  • getEntryScanQuery извлича списък с елементи. Посочваме само id от <Entry/>. Можем (по избор) да предоставим диапазон (масив на Javascript) на долната и горната граница на primaryKey или rangeKey.

В нашия пример искаме да получим всички статии. Тъй като нямаме нито primaryKey, нито rangeKey, използваме функцията getEntryScanQuery. Предоставяме id от <ArticleEntry/> като параметър. Това извлича всички articles от базата данни.

<Query/>-компонентът предоставя три стойности на своите деца: loading, data и error. Тези стойности представляват текущото състояние на заявката за база данни.

  • Докато заявката се изпълнява, loading се дефинира.
  • Когато заявката се върне с грешка, error съдържа съобщението.
  • Когато заявката е успешна, се дефинира data. Това е Javascript обект. Ключът, който съдържа нашия списък с articles, е scan_article. Този ключ е резултат от вида на заявката, която използваме (scan) и id на <ArticleEntry/>.

Добавяне на етикет към статия

Сега нека добавим тагове към статиите, които имаме в нашата база данни. Можем да направим това с <Mutation/>-компонента. Но нека използваме друг начин: React-hooks.

Потребителският интерфейс съдържа <input/> и <button/>. <input/> се свързва с местното състояние. Точно както го правехме преди.

<button/> задейства съхраняването на стойностите в базата данни. Точно както го направихме преди, отново.

Разликата е как създаваме функцията, която да бъде задействана. Този път използваме функцията createSetMutation (използвайте за добавяне или промяна на елемент), която withDataLayer инжектира в нашия props. Тази функция приема функцията useMutation, която импортираме от "@apollo/react-hooks".

Останалото пак е същото. Предоставяме id на <Entry/> и стойностите на primaryKey (articleid) и rangeKey (tag).

Получаваме articleid от родителя на компонента.

Ако искате да изтриете елемент от базата данни, можете да използвате функцията createDeleteMutation.

Показване на етикет

Разбира се, искаме да покажем етикетите на article. И си прав. Можем да използваме и React-hooks за запитване към данни.

Следният код показва article-компонента.

Този компонент показва подробностите за article, които получаваме като props от родителския компонент. С articleid отправяме заявки към присвоените tags.

withDataLayer инжектира функцията createQuery в нашия props. Това приема функцията useQuery като параметър, който импортираме от "@apollo/react-hooks".

Останалото трябва да изглежда познато. Използваме getEntryListQuery от withDataLayer. Този път имаме стойността на primaryKey. И така, предоставяме Javascript обект с един ключ. Това е името на primaryKey (articleid). Присвоената стойност е articleid, което търсим.

Подобно на <Query/>-компонента, React-hook също предоставя три стойности: loading, error и data. Те се държат точно както в нашия пример по-горе.

Този път можете да намерите списъка с tags в обекта с ключ list_tag_articleid. Този ключ е резултат от вида на заявката, която използваме (list), id на <Entry/> (tag) и приложения филтър (articleid).

Вижте вашата база данни в действие

Ако все още не сте стартирали приложението си, добър момент е да го направите сега: npm run start-{your-env-name}.

Можете дори да внедрите приложението си в AWS с една команда: npm run deploy-{your-env-name}. (Не забравяйте да поставите идентификационните данни на AWS в .env-файла).

Поддръжка и ресурси

Можете да правите много страхотни неща с бекенд база данни. Може би искате да добавите бекенд услуги към приложението си? Тази публикация ви показва как да ги добавите и как да извикате вашата база данни от тях.

„Искате ли да станете full-stack разработчик на React?“

С React, можете да отделите съдържанието, стила, оформлението, състоянието и инфраструктурата на вашето приложение.

Ще намерите изходния код на този пример в това хранилище на GitHub.

Инфраструктурни компоненти са в процес на активно развитие. Ако откриете грешка, вашето внедряване изведе грешка или когато имате нужда от всякаква поддръжка, моля, докладвайте на https://spectrum.chat/infrastructure. Благодаря ти!

Документацията описва как да използвате Infrastructure-Components по-подробно.

Компонентите на инфраструктурата са с отворен код! Ето GitHub-репозитория.