Now Reading
Introducing the TERN stack and the best way to migrate from MERN to TERN

Introducing the TERN stack and the best way to migrate from MERN to TERN

2023-05-01 09:42:04

The MERN Stack – an online know-how stack consisting of MongoDB, Categorical.js,
React, and Node.js – was launched round 2018 as a preferred set of applied sciences
to allow end-to-end growth in JavaScript. Though the recognition of
fullstack frameworks akin to Subsequent.js implys that MERN is not as in style because it
as soon as was, it’s nonetheless a viable and productive selection with its decoupled
structure offering extra flexibility than you may get with a fullstack
framework.

In the present day, I would prefer to introduce the TERN (Tigris, Express.js,
React, and Node.js) stack which replaces MongoDB with Tigris.

Migrating from MERN to TERN

On this publish, you may study MERN and TERN and why you must migrate from
MERN to TERN. We’ll cowl all of the steps concerned in migrating a MERN utility
to TERN (Tigris, Express.js, React, and Node.js); first
utilizing
Tigris MongoDB compatibility
to get your present utility working with Tigris as a substitute of MongoDB with out
any code modifications (⚠️ spoiler: it is so simple as updating the MongoDB connection
string). Then, we’ll make just a few modifications to get the applying utilizing the Tigris
SDK as a substitute of the MongoDB Node.js driver, finishing the migration.

What’s MERN?

MERN (MongoDB, Express.js, React, and Node.js) is an
various to the MEAN (MongoDB, Categorical.js, Angular, and Node.js).
MEAN was introduced
in 2013 and MERN adopted as React grew to become more and more in style in 2018.

The MERN stack consists of:

  • Browser: React with both JavaScript or TypeScript
    (transpiled to JavaScript)
  • Server: Express.js with both JavaScript or
    TypeScript (transpiled to JavaScript)
  • Database: MongoDB most definitely utilizing the
    MongoDB Node.js driver, though an ODM akin to
    Mongoose perhaps used.

MERN stack

What’s TERN?

TERN (Tigris, Express.js, React, and Node.js) takes the
concepts behind MERN and replaces MongoDB with Tigris.

TERN stack

Why migrate from MERN to TERN?

So, why would you migrate from MERN (MongoDB) to TERN (Tigris)? Tigris is a
serverless NoSQL database and search platform and an various to MongoDB.

Tigris has a number of advantages over MongoDB. Tigris:

Satisfied? If sure, incredible! If not,
let us know why.

Easy methods to migrate from MERN to TERN

To observe alongside, you may want the next:

For this tutorial, we’ll use a forked and barely up to date model of the
MongoDB MERN example
used within the
official MongoDB MERN stack guide.

The
updates that have been applied
are to make use of the most recent model of the MongoDB Node.js driver (for MongoDB 6.0+
wire protocol help), take away the unused Mongoose ODM dependency, replace the
code to make use of Guarantees, outline the database title in an atmosphere variable, use
encodeURIComponent when passing parameters in URLs from the shopper, and add
alt tags to photographs (not important for this tutorial, however it felt just like the
proper factor to do).

To observe alongside, clone the up to date
TERN stack example repo
and swap to the mern department:

git clone https://github.com/tigrisdata-community/tern-stack-example.git
cd tern-stack-example
git checkout mern

When you have a MongoDB occasion working, you’ll be able to attempt the MERN instance out by
following the directions within the README.

We will now start the migration.

You’ll be able to migrate from MERN to TERN (and from any MongoDB utility to Tigris)
in both a one or two-step course of.

The 2-step course of, and the method lined right here, is:

  1. Start by using Tigris MongoDB Compatibility
  2. Migrating your code to using the Tigris TypeScript SDK

Utilizing Tigris MongoDB Compatibility

We lately launched
Tigris MongoDB compatibility in beta
which lets you hook up with Tigris utilizing the MongoDB 6.0+ wire protocol. From
a MERN perspective, this in all probability means an utility that’s utilizing the
MongoDB Node.js driver.

Updating the applying we have simply cloned to make use of Tigris MongoDB Compatibility is so simple as updating the connection string. So, head to theTigris Console and create a brand new mission. You may then land in your mission’s **Getting Began** part. From there, click on the **MongoDB Compatibility** tab and the MongoDB connection string that you simply see on that tab.

Both replace or create a mern/server/config.env file, setting the worth of
ATLAS_URI to the Tigris MongoDB connection string. Additionally, set DATABASE_NAME
to the title of the Tigris mission you simply created. Your file will look related
to the next:

mern/server/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

Then, observe the present README directions to start out the server and the
shopper.

In a single terminal, begin the server with:

cd mern/server
npm set up
npm begin
Server command line output
$ npm begin

> server@1.0.0 begin
> node server.js

Server is working on port: 5000
Efficiently linked to MongoDB.

In one other terminal, begin the shopper with:

cd mern/shopper
npm set up
npm begin
Consumer command line output

Observe: Another dependencies may do with being up to date.

Compiled with warnings.

Warning
(3769:3) autoprefixer: Change color-adjust to print-color-adjust. The colour-adjust shorthand is at the moment deprecated.

Seek for the key phrases to be taught extra about every warning.
To disregard, add // eslint-disable-next-line to the road earlier than.

WARNING in ./node_modules/bootstrap/dist/css/bootstrap.css (./node_modules/css-loader/dist/cjs.js??ruleSet[1].guidelines[1].oneOf[5].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].guidelines[1].oneOf[5].use[2]!./node_modules/source-map-loader/dist/cjs.js!./node_modules/bootstrap/dist/css/bootstrap.css)
Module Warning (from ./node_modules/postcss-loader/dist/cjs.js):
Warning

(3769:3) autoprefixer: Change color-adjust to print-color-adjust. The colour-adjust shorthand is at the moment deprecated.

webpack compiled with 1 warning

Whenever you run the shopper, the browser robotically opens the browser. By
default, the app will probably be working on http://localhost:3000. Check out the
utility to see it in motion.

Please keep in mind that all we have finished to make this utility work with Tigris
Database is up to date the connection string to level to Tigris Cloud.

Migrating from the MongoDB Node.js Driver to the Tigris SDK

Tigris MongoDB compatibility is a good first step in migrating a MERN
utility. However, to take full benefit of TERN and Tigris, it is advisable
that the applying is up to date to make use of the
Tigris TypeScript SDK.
There’s extra work required to do that, however the modifications are fairly small, as this
part will present.

Because the shopper and server are decoupled by way of the API that the Categorical.js
utility exposes, we solely have to replace the code for the Categorical.js API
endpoints.

Replace dependencies

Let’s start by updating the MERN utility dependencies to make use of these required
by TERN; take away the mongodb driver and add @tigrisdata/core:

npm uninstall monodb
npm i @tigrisdata/core

Add Tigris Configuration

Replace the mern/server/config.env file to include further Tigris config:

mern/server/config.env

- ATLAS_URI=mongodb+srv://<username>:<password>@sandbox.jadwj.mongodb.web/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=primary

Changing {TIGRIS_CLIENT_ID} and {TIGRIS_CLIENT_SECRET} with actual values
out of your Tigris mission utility keys.

Outline your database schema in TypeScript

Set up TypeScript as a growth dependency:

Add the next to a mern/server/tsconfig.json:

mern/server/tsconfig.json

{
"compilerOptions": {
"goal": "es2016",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"module": "commonjs",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
}
}

Outline a schema in TypeScript to match the auto-generated schema that was
created when utilizing the applying by way of Tigris MongoDB compatibility:

import {
Subject,
PrimaryKey,
TigrisCollection,
TigrisDataTypes,
} from "@tigrisdata/core";

@TigrisCollection("data")
export class Report {
@Subject({ parts: TigrisDataTypes.STRING })
$ok?: string[];

@PrimaryKey(TigrisDataTypes.BYTE_STRING, { order: 1, autoGenerate: true })
_id?: string;

@Subject()
title!: string;

@Subject()
place!: string;

@Subject()
degree!: string;
}

The @TigrisCollection("data") decorator and equipped data worth
informs Tigris that there’s a data assortment of paperwork of kind
Report within the construction outlined by that class.

The fields _id, title, place, and degree, are all used inside the
utility. The $ok subject is not used however is required to permit the applying
to proceed to work with the auto-generated MongoDB compatibility schema. As
you may see, all the applying’s fields are of kind string.

You can too seize this schema from the Tigris
Console
below Your Undertaking -> Database -> click on on the data
schema -> choose TypeScript from the drop down:

The record schema defined in TypeScript within the Tigris Console

With the schema in place, we have to validate it with Tigris and use it with the
Tigris TypeScript SDK. To do this, create a mern/server/script/setup.ts script
with the next contents:

mern/server/scripts/setup.ts

import { Tigris } from "@tigrisdata/core";
import { Report } from "../db/report";

import dotenv from "dotenv";
dotenv.config({ path: "./config.env" });

async operate primary() {

const tigrisClient = new Tigris();

await tigrisClient.getDatabase().initializeBranch();

await tigrisClient.registerSchemas([Record]);
}

primary()
.then(async () => {
console.log("Setup full ...");
course of.exit(0);
})
.catch(async (e) => {
console.error(e);
course of.exit(1);
});

Within the above code, the config is loaded utilizing dotenv, and a Tigris shopper is
instantiated and assigned to the tigrisClient variable, which makes use of the loaded
atmosphere variables. Then, the database and database department are initialized by
tigrisClient.getDatabase().initializeBranch(). Lastly, register the Report
schema by way of tigrisClient.registerSchemas([Record]).

Replace the package deal.json to utilize the setup script:

{
"title": "server",
"model": "1.0.0",
"description": "",
"primary": "server.js",
"scripts": {
+ "setup": "npx ts-node scripts/setup.ts",
+ "prestart": "npm run setup",
"check": "echo "Error: no check specified" && exit 1"
},
"key phrases": [],
"creator": "",
"license": "ISC",
"dependencies": {
+ "@tigrisdata/core": "^1.0.0-beta.44",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"categorical": "^4.17.1",
- "mongodb": "5.2",
- "mongoose": "^5.12.4"
+ "reflect-metadata": "^0.1.13"
+ },
+ "devDependencies": {
+ "typescript": "^5.0.4"
}
}

This provides a setup NPM script utilized by prestart, which is robotically
earlier than the script outlined within the begin NPM script.

Observe: the above diff additionally reveals the opposite modified dependencies.

With the schema outlined, we are able to transfer on to updating the applying code.

Replace the connection code

Subsequent, replace the connection code outlined in mern/server/db/conn.js by eradicating
the MongoDB Node.js driver and updating the code to make use of the Tigris TypeScript
SDK:

mern/server/db/conn.js

- const { MongoClient } = require("mongodb");
- const Db = course of.env.ATLAS_URI;
+ const { Tigris } = require("@tigrisdata/core");

- const shopper = new MongoClient(Db, {
- useNewUrlParser: true,
- useUnifiedTopology: true,
- });
+ const shopper = new Tigris();

var _db;

module.exports = {
connectToServer: async operate (callback) {
attempt {
- const db = await shopper.join();
- _db = db.db(course of.ENV.DATABASE_NAME);
- console.log("Efficiently linked to MongoDB.");
+ _db = await shopper.getDatabase();
+ console.log("Efficiently linked to Tigris.");
return callback();
} catch (err) {
return callback(err);

The Tigris shopper is instantiated and robotically makes use of the atmosphere
variables we have outlined within the mern/server/config.env file.

The opposite distinction price stating is that we do not title the database that
is being utilized in shopper.getDatabase() since every Tigris Undertaking has just one
database.

Frequent MERN to TERN code modifications

A constant distinction throughout the entire Categorical.js route modifications are:

  1. The MongoDB ObjectId is now not used
  2. The question comprises a filter to establish the doc. So, from
    { _id: new ObjectId(req.params.id) } to
    { filter: { _id: req.params.id } } is a constant code change in all
    routes
  3. Collections are accessed by way of getCollection(collectionName) as a substitute of
    assortment(collectionName)

Migrate MERN database learn to TERN database learn

Replace the GET /report route:

mern/server/routes/report.js

See Also

- const ObjectId = require("mongodb").ObjectId;

// This part will show you how to get a listing of all of the data.
recordRoutes.route("/report").get(async operate (req, res) {
- let db_connect = dbo.getDb("staff");
- const outcome = await db_connect.assortment("data").discover({}).toArray();
+ let db_connect = dbo.getDb();
+ const outcome = await db_connect.getCollection("data").findMany().toArray();

return res.json(outcome);
});

To retrieve a number of paperwork utilizing the Tigris SDK use
findMany,
passing no parameters. This returns a cursor that exposes a toArray operate
to get an Array of outcomes.

Should you restart the server utility, you may see the principle utility web page
displaying the workers however by way of a name to GET /report which now makes use of the
Tigris SDK.

Migrate MERN database create to TERN database create

Replace the POST /report/add route:

Observe: To be extra devoted to REST, this must be POST /report

mern/server/routes/report.js

recordRoutes.route("/report/add").publish(async operate (req, res) {
let db_connect = dbo.getDb();
let myobj = {
title: req.physique.title,
place: req.physique.place,
degree: req.physique.degree,
};

- const outcome = db_connect.assortment("data").insertOne(myobj);
+ const outcome = await db_connect.getCollection("data").insertOne(myobj);
res.json(outcome);
});

On this case, the strategy signature for
insertOne
stays the identical.

Migrate MERN database replace to TERN database replace

Change the POST /replace/:id route:

Observe: To be extra RESTful, this must be PATCH /report/:id or
PATCH /report/:id if it replaces the entire useful resource.

mern/server/routes/report.js

recordRoutes.route("/replace/:id").publish(async operate (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: {
title: req.physique.title,
place: req.physique.place,
degree: req.physique.degree,
},
+ },
};
- const outcome = await db_connect
- .assortment("data")
- .updateOne(myquery, newvalues);
+ const outcome = await db_connect.getCollection("data").updateOne(myquery);

console.log("1 doc up to date");
res.json(outcome);
});

The
updateOne
Tigris SDK operate differs from the MongoDB Node.js driver in that, it takes a
single parameter with the next properties to realize the identical outcome:

  1. filter the filter used to seek out the only doc to be up to date
  2. fields the place this property can use the $set syntax supported by the
    MongoDB driver.

Migrate MERN database delete to TERN database delete

Lastly, replace the DELETE /:id route:

Observe: REST police: this must be DELETE /report/:id

mern/server/routes/report.js

recordRoutes.route("/:id").delete(async (req, res) => {
let db_connect = dbo.getDb();
- let myquery = { _id: new ObjectId(req.params.id) };
- const outcome = await db_connect.assortment("data").deleteOne(myquery);
+ let myquery = { filter: { _id: req.params.id } };
+ const outcome = await db_connect.getCollection("data").deleteOne(myquery);

res.json(outcome);
});

As mentioned, the one change right here is the filter required by the Tigris SDK.

Let’s add the Tigris emblem ???? Seize the
Tigris green logo,
put it aside to tern/shopper/public and replace
mern/shopper/src/parts/navbar.js as follows:

mern/shopper/src/parts/navbar.js

<NavLink className="navbar-brand" to="/">
<img
- alt="MongoDB emblem"
+ alt="Tigris emblem"
type={{ width: 25 + "%" }}
- src="https://d3cy9zhslanhfa.cloudfront.web/media/3800C044-6298-4575-A05D5C6B7623EE37/4B45D0EC-3482-4759-82DA37D8EA07D229/webimage-8A27671A-8A53-45DC-89D7BF8537F15A0D.png"
+ src="/tigris-logo-green.png"
></img>
</NavLink>

Run the TERN utility

And with these updates utilized, the MERN utility is transformed to the TERN
stack ????

Since there are not any practical modifications to the front-end (solely the brand replace),
you solely have to cease and begin the server solely to see the modifications in motion:

And you may see the next output:

npm begin

> server@1.0.0 prestart
> npm run setup


> server@1.0.0 setup
> npx ts-node scripts/setup.ts

data - Utilizing reflection to deduce kind of Report#$ok
data - Utilizing reflection to deduce kind of Report#title
data - Utilizing reflection to deduce kind of Report#place
data - Utilizing reflection to deduce kind of Report#degree
data - Utilizing Tigris at: api.preview.tigrisdata.cloud:443
data - Utilizing database department: 'primary'
occasion - Creating assortment: 'data' in mission: 'mern-to-tern'
Setup full ...

> server@1.0.0 begin
> node server.js

data - Utilizing Tigris at: api.preview.tigrisdata.cloud:443
Server is working on port: 5000
Efficiently linked to Tigris.

Navigate to the shopper URL, which by default is http://localhost:3000, and take a look at
out the TERN app (we did refresh the shopper so the Tigris emblem is current in
this video):

When you have a take a look at the Tigris Console
and discover the information, as proven within the video, you may see the _id values are
structured in another way, and the $ok worth is just not populated for paperwork
created by way of the Tigris SDK.

Apart from the brand, the applying appears and performs precisely because the MERN
utility did. Nonetheless, because the intro outlines, now you can additionally take benefit
of the advantages of utilizing Tigris.

You will discover all of the code modifications utilized emigrate the MongoDB MERN
utility to TERN in
this diff.

Subsequent Steps

How about elevating a pull request so as to add full-text search to the TERN utility
utilizing
Tigris Search?

What ought to we name the Tigris model of MEAN? No, I’ve obtained it; it must be
NEAT!

Be a part of the Tigris Discord and tell us
what you consider TERN and the method of migrating a MERN (or another
MongoDB) utility over to TERN.

Tigris is an open-source serverless NoSQL database and search platform. Should you
have any questions, otherwise you’d prefer to contribute to the
Tigris open source project.

Source Link

What's Your Reaction?
Excited
0
Happy
0
In Love
0
Not Sure
0
Silly
0
View Comments (0)

Leave a Reply

Your email address will not be published.

2022 Blinking Robots.
WordPress by Doejo

Scroll To Top