Знакомство со стеком TERN и переходом с MERN на TERN. MERN — это стек веб-технологий, состоящий из MongoDB, Express.js, React и Node.js. В этом руководстве предполагается, что вы используете Tigris Cloud или собственный экземпляр Tigris.
Что такое МЕРН?
MERN (MongoDB, Express.js, React и Node.js) является альтернативой MEAN (MongoDB, Express.js, Angular и Node.js). MEAN был представлен в 2013 году, а MERN последовал за ним по мере того, как React становился все более популярным в 2018 году.
Стек MERN состоит из:
- Браузер: React с помощью JavaScript или TypeScript (перенесено в JavaScript)
- Сервер: Express.js с JavaScript или TypeScript (переведено в JavaScript)
- База данных: MongoDB, скорее всего, использует драйвер MongoDB Node.js, хотя может использоваться ODM, такой как Mongoose.
Что такое ТЕРН?
TERN (Tigris, Express.js, React и Node.js) использует идеи MERN и заменяет MongoDB на Tigris.
- Браузер: React с помощью JavaScript или TypeScript (перенесено в JavaScript)
- Сервер: Express.js с JavaScript или TypeScript (переведено в JavaScript)
- База данных: Tigris Database с использованием Tigris TypeScript SDK, который предоставляет встроенный ODM.
Зачем переходить с MERN на TERN?
Итак, зачем вам переходить с MERN (MongoDB) на TERN (Tigris)? Tigris — это бессерверная база данных NoSQL и поисковая платформа, а также альтернатива MongoDB.
У Tigris есть несколько преимуществ перед MongoDB. Тигр:
- Использует подход, основанный на коде, к моделированию схемы базы данных и моделированию поискового индекса.
- Поддерживает ветвление базы данных, чтобы вписаться в ваш рабочий процесс разработки.
- Устраняет необходимость ручной подготовки кластера и управления сегментами.
- Поддерживает ACID-транзакции без оговорок.
- Обеспечивает одинаковую функциональность полнотекстового поиска независимо от того, используете ли вы Tigris Cloud или собственный хостинг. Функциональность текстового поиска MongoDB различается между MongoDB Atlas и собственной MongoDB.
- Создан с использованием современной облачной архитектуры, что означает, что эксплуатационные расходы ниже, чем у MongoDB.
Убежденный? Если да, то фантастика! Если нет, дайте нам знать, почему.
Как перейти с MERN на TERN
Чтобы следовать дальше, вам понадобится следующее:
- Установлен Node.js LTS или выше
- Учетная запись Tigris Cloud или самостоятельный экземпляр Tigris. В этом руководстве предполагается, что вы используете Tigris Cloud.
В этом руководстве мы будем использовать разветвленную и слегка обновленную версию примера MongoDB MERN, используемого в официальном руководстве по стеку MongoDB MERN.
Примененные обновления заключаются в использовании новейшей версии драйвера MongoDB Node.js (для поддержки сетевого протокола MongoDB 6.0+), удалении неиспользуемой зависимости Mongoose ODM, обновлении кода для использования промисов, определении имени базы данных в переменная среды, используйте encodeURIComponent
при передаче параметров в URL-адресах от клиента и добавляйте теги alt
к изображениям (не обязательно для этого руководства, но мне показалось, что это правильно).
Чтобы продолжить, клонируйте обновленный репозиторий пример стека TERN и переключитесь на ветку mern
:
git clone https://github.com/tigrisdata-community/tern-stack-example.git cd tern-stack-example git checkout mern
Если у вас запущен экземпляр MongoDB, вы можете попробовать пример MERN, следуя инструкциям в файле README.
Теперь мы можем начать миграцию.
Вы можете перейти с MERN на TERN (и с любого приложения MongoDB на Tigris) в один или два этапа.
Двухэтапный процесс, описанный здесь, таков:
- Начните с использования совместимости с Tigris MongoDB
- Перенос вашего кода на использование Tigris TypeScript SDK
Использование совместимости с Tigris MongoDB
Недавно мы выпустили бета-версию Совместимость с Tigris MongoDB, которая позволяет подключаться к Tigris с использованием проводного протокола MongoDB 6.0+. С точки зрения MERN это, вероятно, означает приложение, использующее драйвер MongoDB Node.js.
Обновить приложение, которое мы только что клонировали, для использования совместимости с Tigris MongoDB так же просто, как обновить строку подключения. Итак, заходим в Tigris Console и создаем новый проект. Затем вы попадете в раздел **Начало работы** вашего проекта. Оттуда щелкните вкладку **Совместимость с MongoDB** и строку подключения MongoDB, которую вы видите на этой вкладке.
Либо обновите, либо создайте файл mern/server/config.env
, установив значение ATLAS_URI
в строку подключения Tigris MongoDB. Кроме того, установите DATABASE_NAME
на имя только что созданного проекта Tigris. Ваш файл будет выглядеть примерно так:
мерн/сервер/config.env
ATLAS_URI=mongodb://{TIGRIS_CLIENT_ID}:{TIGRIS_CLIENT_SECRET}@m1k.preview.tigrisdata.cloud:27018?authMechanism=PLAIN&tls=true DATABASE_NAME=mern-to-tern
Затем следуйте существующим инструкциям README, чтобы запустить сервер и клиент.
В одном терминале запустите сервер с помощью:
cd mern/server npm install npm start
Вывод командной строки сервера
В другом терминале запустите клиент с помощью:
cd mern/client npm install npm start
Вывод командной строки клиента
Когда вы запускаете клиент, браузер автоматически открывает браузер. По умолчанию приложение будет работать на http://localhost:3000
. Попробуйте приложение, чтобы увидеть его в действии.
Помните, что все, что мы сделали, чтобы это приложение работало с базой данных Tigris, — это обновили строку подключения, чтобы она указывала на Tigris Cloud.
Миграция с драйвера MongoDB Node.js на Tigris SDK
Совместимость с Tigris MongoDB — отличный первый шаг в миграции приложения MERN. Но чтобы в полной мере воспользоваться преимуществами TERN и Tigris, рекомендуется обновить приложение для использования Tigris TypeScript SDK. Для этого требуется больше работы, но изменения довольно небольшие, как будет показано в этом разделе.
Поскольку клиент и сервер отделены через API, предоставляемый приложением Express.js, нам нужно обновить код только для конечных точек API Express.js.
Обновить зависимости
Начнем с обновления зависимостей приложения MERN, чтобы использовать те, которые требуются TERN; удалите драйвер mongodb
и добавьте @tigrisdata/core
:
npm uninstall monodb npm i @tigrisdata/core
Добавить конфигурацию Tigris
Обновите файл mern/server/config.env
, чтобы он содержал дополнительную конфигурацию Tigris:
мерн/сервер/config.env
- ATLAS_URI=mongodb+srv://<username>:<password>@sandbox.jadwj.mongodb.net/myFirstDatabase?retryWrites=true&w=majority - DATABASE_NAME=mern-to-tern PORT=5000 + TIGRIS_CLIENT_ID={TIGRIS_CLIENT_ID} + TIGRIS_CLIENT_SECRET={TIGRIS_CLIENT_SECRET} + TIGRIS_PROJECT=mern-to-tern + TIGRIS_URI=api.preview.tigrisdata.cloud + TIGRIS_DB_BRANCH=main
Замена {TIGRIS_CLIENT_ID}
и {TIGRIS_CLIENT_SECRET}
реальными значениями из ключей приложения вашего проекта Tigris.
Определите схему вашей базы данных в TypeScript
Установите TypeScript как зависимость разработки:
npm i -D typescript
Добавьте следующее к mern/server/tsconfig.json
:
мерн/сервер/tsconfig.json
{ "compilerOptions": { "target": "es2016", "experimentalDecorators": true, "emitDecoratorMetadata": true, "module": "commonjs", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true } }
Определите схему в TypeScript, чтобы она соответствовала автоматически сгенерированной схеме, созданной при использовании приложения через совместимость с Tigris MongoDB:
import { Field, PrimaryKey, TigrisCollection, TigrisDataTypes, } from "@tigrisdata/core"; @TigrisCollection("records") export class Record { @Field({ elements: TigrisDataTypes.STRING }) $k?: string[]; @PrimaryKey(TigrisDataTypes.BYTE_STRING, { order: 1, autoGenerate: true }) _id?: string; @Field() name!: string; @Field() position!: string; @Field() level!: string; }
Декоратор @TigrisCollection("records")
и предоставленное значение records
информируют Tigris о наличии records
коллекции документов типа Record
в структуре, определенной этим классом.
Поля _id
, name
, position
и level
используются в приложении. Поле $k
не используется, но необходимо, чтобы приложение могло продолжать работать с автоматически созданной схемой совместимости MongoDB. Как вы увидите, все поля приложения имеют тип string
.
КОНЧИК
Вы также можете получить эту схему из Консоли Tigris в разделе Ваш проект -> База данных -> щелкните по схеме записей -> выберите TypeScript из выпадающего списка:
Имея схему, нам нужно проверить ее с помощью Tigris и использовать с SDK Tigris TypeScript. Для этого создайте скрипт mern/server/script/setup.ts
со следующим содержимым:
мерн/сервер/скрипты/setup.ts
import { Tigris } from "@tigrisdata/core"; import { Record } from "../db/record"; import dotenv from "dotenv"; dotenv.config({ path: "./config.env" }); async function main() { // setup client const tigrisClient = new Tigris(); // ensure branch exists, create it if it needs to be created dynamically await tigrisClient.getDatabase().initializeBranch(); // register schemas await tigrisClient.registerSchemas([Record]); } main() .then(async () => { console.log("Setup complete ..."); process.exit(0); }) .catch(async (e) => { console.error(e); process.exit(1); });
В приведенном выше коде конфигурация загружается с использованием dotenv
, а клиент Tigris
создается и назначается переменной tigrisClient
, которая использует загруженные переменные среды. Затем база данных и ветвь базы данных инициализируются с помощью tigrisClient.getDatabase().initializeBranch()
. Наконец, зарегистрируйте схему Record
через tigrisClient.registerSchemas([Record])
.
Обновите package.json
, чтобы использовать сценарий установки:
{ "name": "server", "version": "1.0.0", "description": "", "main": "server.js", "scripts": { + "setup": "npx ts-node scripts/setup.ts", + "prestart": "npm run setup", "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { + "@tigrisdata/core": "^1.0.0-beta.44", "cors": "^2.8.5", "dotenv": "^8.2.0", "express": "^4.17.1", - "mongodb": "5.2", - "mongoose": "^5.12.4" + "reflect-metadata": "^0.1.13" + }, + "devDependencies": { + "typescript": "^5.0.4" } }
Это добавляет сценарий setup
NPM, используемый prestart
, который автоматически предшествует сценарию, определенному в сценарии start
NPM.
Примечание: приведенный выше diff также показывает другие измененные зависимости.
Определив схему, мы можем перейти к обновлению кода приложения.
Обновить код подключения
Затем обновите код подключения, определенный в mern/server/db/conn.js
, удалив драйвер MongoDB Node.js и обновив код для использования SDK Tigris TypeScript:
Мерн/сервер/БД/conn.js
- const { MongoClient } = require("mongodb"); - const Db = process.env.ATLAS_URI; + const { Tigris } = require("@tigrisdata/core"); - const client = new MongoClient(Db, { - useNewUrlParser: true, - useUnifiedTopology: true, - }); + const client = new Tigris(); var _db; module.exports = { connectToServer: async function (callback) { try { - const db = await client.connect(); - _db = db.db(process.ENV.DATABASE_NAME); - console.log("Successfully connected to MongoDB."); + _db = await client.getDatabase(); + console.log("Successfully connected to Tigris."); return callback(); } catch (err) { return callback(err);
Клиент Tigris
создается и автоматически использует переменные среды, которые мы определили в файле mern/server/config.env
.
Другое отличие, на которое стоит обратить внимание, заключается в том, что мы не называем базу данных, которая используется в client.getDatabase()
, поскольку каждый проект Tigris имеет только одну базу данных.
Общие изменения кода MERN в TERN
Постоянная разница во всех изменениях маршрута Express.js:
- MongoDB
ObjectId
больше не используется - Запрос содержит
filter
для идентификации документа. Итак, с{ _id: new ObjectId(req.params.id) }
на{ filter: { _id: req.params.id } }
последовательное изменение кода во всех маршрутах - Доступ к коллекциям осуществляется через
getCollection(collectionName)
вместоcollection(collectionName)
Перенос базы данных MERN для чтения в базу данных TERN для чтения
Обновите маршрут GET /record
:
мерн/сервер/маршруты/record.js
- const ObjectId = require("mongodb").ObjectId; // This section will help you get a list of all the records. recordRoutes.route("/record").get(async function (req, res) { - let db_connect = dbo.getDb("employees"); - const result = await db_connect.collection("records").find({}).toArray(); + let db_connect = dbo.getDb(); + const result = await db_connect.getCollection("records").findMany().toArray(); return res.json(result); });
Чтобы получить несколько документов с помощью Tigris SDK, используйте findMany
, не передавая никаких параметров. Это возвращает курсор, который предоставляет функцию toArray
для получения Array
результатов.
Если вы перезапустите серверное приложение, вы увидите главную страницу приложения, на которой отображаются сотрудники, но через вызов GET /record
, который теперь использует Tigris SDK.
Перенос базы данных MERN create в базу данных TERN create
Обновите маршрут POST /record/add
:
Примечание. Чтобы быть более верным REST, это должно быть POST /record
мерн/сервер/маршруты/record.js
recordRoutes.route("/record/add").post(async function (req, res) { let db_connect = dbo.getDb(); let myobj = { name: req.body.name, position: req.body.position, level: req.body.level, }; - const result = db_connect.collection("records").insertOne(myobj); + const result = await db_connect.getCollection("records").insertOne(myobj); res.json(result); });
В этом случае сигнатура метода для insertOne
остается прежней.
Перенести обновление базы данных MERN в обновление базы данных TERN
Измените маршрут POST /update/:id
:
Примечание. Для большего удобства REST это должно быть PATCH /record/:id
или PATCH /record/:id
, если он заменяет весь ресурс.
мерн/сервер/маршруты/record.js
recordRoutes.route("/update/:id").post(async function (req, res) { let db_connect = dbo.getDb(); - let myquery = { _id: new ObjectId(req.params.id) }; - let newvalues = { + const myquery = { + filter: { _id: req.params.id }, + fields: { $set: { name: req.body.name, position: req.body.position, level: req.body.level, }, + }, }; - const result = await db_connect - .collection("records") - .updateOne(myquery, newvalues); + const result = await db_connect.getCollection("records").updateOne(myquery); console.log("1 document updated"); res.json(result); });
Функция updateOne
Tigris SDK отличается от драйвера MongoDB Node.js тем, что она принимает один параметр со следующими свойствами для достижения того же результата:
filter
фильтр, используемый для поиска документа, который нужно обновитьfields
, где это свойство может использовать синтаксис$set
, поддерживаемый драйвером MongoDB.
Перенести удаление базы данных MERN на удаление базы данных TERN
Наконец, обновите маршрут DELETE /:id
:
Примечание. Полиция REST: это должно быть DELETE /record/:id
мерн/сервер/маршруты/record.js
recordRoutes.route("/:id").delete(async (req, res) => { let db_connect = dbo.getDb(); - let myquery = { _id: new ObjectId(req.params.id) }; - const result = await db_connect.collection("records").deleteOne(myquery); + let myquery = { filter: { _id: req.params.id } }; + const result = await db_connect.getCollection("records").deleteOne(myquery); res.json(result); });
Как уже говорилось, единственное изменение здесь — это filter
, требуемый для Tigris SDK.
Обновить логотип
Давайте добавим логотип Tigris 😄 Возьмите Зеленый логотип Tigris, сохраните его в tern/client/public
и обновите mern/client/src/components/navbar.js
следующим образом:
Мерн/клиент/SRC/компоненты/navbar.js
<NavLink className="navbar-brand" to="/"> <img - alt="MongoDB logo" + alt="Tigris logo" style={{ width: 25 + "%" }} - src="https://d3cy9zhslanhfa.cloudfront.net/media/3800C044-6298-4575-A05D5C6B7623EE37/4B45D0EC-3482-4759-82DA37D8EA07D229/webimage-8A27671A-8A53-45DC-89D7BF8537F15A0D.png" + src="/tigris-logo-green.png" ></img> </NavLink>
Запустите приложение TERN
И с применением этих обновлений приложение MERN преобразуется в стек TERN 🎉
Поскольку никаких функциональных изменений во внешнем интерфейсе нет (только обновление логотипа), вам нужно только остановить и запустить сервер только для того, чтобы увидеть изменения в действии:
npm start
И вы увидите следующий вывод:
npm start > [email protected] prestart > npm run setup > [email protected] setup > npx ts-node scripts/setup.ts info - Using reflection to infer type of Record#$k info - Using reflection to infer type of Record#name info - Using reflection to infer type of Record#position info - Using reflection to infer type of Record#level info - Using Tigris at: api.preview.tigrisdata.cloud:443 info - Using database branch: 'main' event - Creating collection: 'records' in project: 'mern-to-tern' Setup complete ... > [email protected] start > node server.js info - Using Tigris at: api.preview.tigrisdata.cloud:443 Server is running on port: 5000 Successfully connected to Tigris.