📜 ⬆️ ⬇️

How to frontend developer set up a database



Recently, I was asked how is it easy for a front-end developer to save user data? Under the cut - my brief instructions for those with databases "on you."

Database Setup


First, we need an up-to-date database. You can make yourself free at mlab . When you register, in the MongoDB Deployments tab, click on create new . DB-sandbox is provided free of charge, we will use it.

After creating the database, you need to create an account for our authentication. Click on the database name, then users , then a dd database user . Save your login / password somewhere, we still need them.
')
At the top of the database page, you will see the MongoDB URI. This is the web address of our database. A URI is like the address of a web page. The URI format for MongoDB URI will be:

mongodb://<dbuser>:<dbpassword>@<host>:<port>/<dbname> 

Here is the URI of my database:

 mongodb://admin:superSecretPassword@ds111885.mlab.com:11885/medium 

Server Tuning


Let's take Node as a backend. In order not to customize it, you can simply click here and clone my project on Glitch.

Take a look at my initial server.js file:

 // init project const express = require('express'); // the library we will use to handle requests const app = express(); // instantiate express app.use(require("cors")()) // allow Cross-domain requests app.use(require('body-parser').json()) // automatically parses request data to JSON // base route app.get("/", function (request, response) { response.send("TODO") // always responds with the string "TODO" }); // base route app.post("/", function (request, response) { response.send("TODO") // always responds with the string "TODO" }); app.put("/", function (request, response) { response.send("TODO") // always responds with the string "TODO" }); // listen for requests, the process.env.PORT is needed because // we are using glitch, otherwise you could have written 80 or whatever var listener = app.listen(process.env.PORT, function () { console.log('Your app is listening on port ' + listener.address().port); }); 

We start by importing express - this is the library that we will use to process requests to the server.

For cross-domain queries, we need use(require(cors)) . These are requests from a website that is hosted in one domain, to a server in another domain.

The app.use(require('body-parser').json()) command automatically parses JSON requests for us.

Then we pass the get route that we want to process, and the processing callback function itself. When someone opens the page / of our site, this request will be processed by a callback. The base domain will be relative, so if you have the address of the website shiny-koala.glitch.com , then the route /about will turn into shiny-koala.glitch.com/about .

Let me explain: by “open page” I mean a request that uses the GET method on your server. HTTP methods are only types of requests that you can address to the server. We will only use these:


app.post and app.put work the same way as app.get , they only process POST and PUT methods instead of GET.

Routing


Once you raise the server, you will need to test it. To run HTTP requests, you can use the convenient REST test test site or the Insomnia application.

To check the URL of your Glitch application, click on the show button.

For now we only use the path /. But we need to store different information about different users, and therefore we need separate paths for each user.

For example: /ZaninAndrea or /JohnGreen .

There was a difficulty: perhaps we cannot write all the ways in the code, this is not a very scalable approach. We need routing options. And in the code we write only one way: /:user

The colon tells Express to catch any path starting with a slash / and then consisting of letters and numbers.

For example:


Then you can return the user value of the variable request.params.user

 // base route app.get("/:user", function (request, response) { response.send(request.params.user) }); // base route app.post("/:user", function (request, response) { response.send(request.params.user) }); // base route app.put("/:user", function (request, response) { response.send(request.params.user) }); 

Now our server answers almost every question with a username.

Adding information to the database


We know who the user is with us, and now we need to save some information about him.
To access the database, we will use the mongodb library. It can be installed in two ways:

 npm install mongodb --save 

or, if you are using Glitch, open the package.json file and click on the Add package button.

Let's load the library and store the MongoDB URI in a variable:

 const mongodb = require('mongodb'); // load mongodb const uri = process.env.URI; 

A URI is very important information, that's all we need to access the database. It is best to put the URI in a .env file that is invisible to others.

 URI=mongodb://admin:PASSWORD@ds111885.mlab.com:11885/medium 

Glitch will automatically load the variables from the .env file into the process.env variable.

Connecting to the database is an asynchronous operation, so you need to wrap the entire server setup in a callback like this:

 mongodb.MongoClient.connect(uri, function(err, db) { // base route app.get("/:user", function (request, response) { response.send(request.params.user) }); // base route app.post("/:user", function (request, response) { response.send(request.params.user) }); // base route app.put("/:user", function (request, response) { response.send(request.params.user) }); // listen for requests, the process.env.PORT is needed because // we are using glitch, otherwise you could have written 80 or whatever var listener = app.listen(process.env.PORT, function () { console.log('Your app is listening on port ' + listener.address().port); }); }) 

Databases are organized as collections, and the collections contain documents (JSON files). Let's connect to the user collection (it will be created when it is first accessed).

 mongodb.MongoClient.connect(uri, function(err, db) { const collection = db.collection('users') // ... } 

First, we need to process the POST path. We will use it when we first add user data. Then we use the PUT method to update the data.

  app.post("/:user", function (request, response) { // inserts a new document on the server collection.insertOne({ ...request.body, user : request.params.user }, function (err, r) { if (err){ response.send("An error occured") }else{ response.send("All well") } }) }); 

The collection.insertOne method adds a new document to the collection. In our case, each user has his own document.

 { ...request.body, user : request.params.user } 

uses the spread-operator to combine the data provided in the request body, as well as transmitted by the user at the URL.

And then it turns out the document stored in the collection.

The second argument is a callback, simply notifying the user of the result of the operation.

Getting information from the database


Now we have some data on the server, and we want to read it. To do this, use the GET method.

 app.get("/:user", function (request, response) { collection.find({ user : request.params.user }).toArray(function (err, docs) { if (err){ response.send("An error occured") }else{ response.send(docs) } }) }); 

This time the first argument will be a filter telling the database to send us only documents with the correct user properties.

Documents are returned to the user in an array, because theoretically there can be more than one document with the properties of this user. And it depends on us whether this can happen.

Updating database information


To update information about an existing user, we use the PUT method.

 // base route app.put("/:user", function (request, response) { collection.updateOne({ user : request.params.user }, {$set:{ ...request.body, user : request.params.user }}, function (err, r) { if (err){ response.send("An error occured") }else{ response.send("All well") } }) }); 

The first argument is a filter, like what we used in the GET method.

The second argument is the update document, you can read more about it here . In this case, we are telling the database to combine the information transmitted by the user with the already existing information.

But be careful, because the embedded parameters will be replaced, not merged.

At last


This is far from an exhaustive guide to databases and backend programming, but it’s quite enough for you to run your personal project.

Perhaps in the future I will write an article on authentication, but for now do not store confidential information in your database.

Source: https://habr.com/ru/post/343334/


All Articles