# 12/8 部課 ## Review: Workflow Ref: https://www.youtube.com/watch?app=desktop&v=YGxrvHGCJ2Y ![image](https://hackmd.io/_uploads/r1Gl_rx8p.png) Frontend to Backend: Application layer(應用層) under TCP/IP model List of Protocols in Application layer: https://www.geeksforgeeks.org/application-layer-protocols-in-tcp-ip/ ### HTTP requests 1. Request Line ![image](https://hackmd.io/_uploads/SJkgprlIa.png) 2. HTTP headers ![image](https://hackmd.io/_uploads/r197pHxLT.png) 3. Message body :::info **GET** Method usually *does not include* message body. ::: > Message bodies are appropriate for some request methods and inappropriate for others. For example, a request with the POST method, which sends input data to the server, has a message body containing the data. A request with the GET method, which asks the server to send a resource, does not have a message body. ### HTTP response 1. Status line 2. HTTP headers ![image](https://hackmd.io/_uploads/BJ9bM8xL6.png) 3. Message body For the example above, it will return corresponding html script. ## Database ### What is a database? > A database, in the most general sense, is an *organized collection of data*. More specifically, a database is an **electronic system** that allows data to be easily accessed, manipulated and updated. > When people refer to a “database” they’re often talking about a computer program that allows them to *interact with their database*. These programs, known more formally as a **database management system (DBMS)**, are often installed on a virtual private server and accessed remotely. ### Relational Databases(RDBMSs) - Data are stored by multiple **tables** - A table is constructed with a set of tuples, or rows in a table, with each tuple sharing a set of attributes, or columns - There exists some explicit relations between data, but only useful if you can retrieve it. ![image](https://hackmd.io/_uploads/HJwcFLxUp.png) (ref: https://www.digitalocean.com/community/conceptual-articles/an-introduction-to-databases) - Uses **Structured Query Language(SQL)** to manage and query data - Examples: MySQL, PostgreSQL, SQLite, ... Problems with RDBMS: - Not always every set of data exist explicit relations with each other - Must specify unique attribute ### Non-relational Databases(NoSQL databases) - Does not implement SQL - Not need relations, being more flexible with data storing - Difficulty of choosing NoSQL ![image](https://hackmd.io/_uploads/SylV76Lg8p.png) ![image](https://hackmd.io/_uploads/SJ_LaIlLp.png) - Redis: Key-Value Databases - MongoDB: Document-Oriented Databases ### Object Relational Mapping (ORM) > When interacting with a database using OOP languages, you'll have to perform different operations like creating, reading, updating, and deleting (CRUD) data from a database. By design, you use **SQL** for performing these operations in relational databases. > While using SQL for this purpose isn't necessarily a bad idea, the ORM and ORM tools help simplify the interaction between relational databases and different OOP languages. For example, if we want to find a todo item named "buying an apple" and haven't done(done = False) in `Todo` database, we can access it by using ORM syntax: ```javascript= Todo.find ({ name: 'buying an apple', done: { false }}) ``` Using SQL syntax: ```sql= SELECT * FROM Todos WHERE name='buying an apple' AND done=FALSE; ``` ### MongoDB - NoSQL, Document-Oriented :::info Document-Oriented: Mixture of Relational & Key-Value Databases ::: - Format ```javascript= Todo.find()[0].username ``` ```jsonld= { "_id": { "$oid": "6572e1cef219bca05511d230" }, "id": { "$numberInt": "1" }, "username": "admin", "passwd": "$2a$10$/sbmKQjOpqfeeZ1gFEyaauNC5GxNL6yTgJP/AIbGCN9DpyxOMv9Ou", "identity": "Admin", "events": [], "isLoggedIn": false, "loggedInAt": { "$date": { "$numberLong": "1672993352831" } }, "__v": { "$numberInt": "0" } } ``` ### MongoDB Atlas - Free service from MongoDB official https://lyunotes.blogspot.com/2020/11/day12-mongodb-atlas.html https://www.mongodb.com/ https://www.mongodb.com/atlas/database ### Start !!! #### Step 1: Connection In `server.js`: ```javascript= const mongoose = require("mongoose"); require("dotenv").config(); const { MONGO_USERNAME, MONGO_PASSWORD } = process.env; const uri = `mongodb+srv://${MONGO_USERNAME}:${MONGO_PASSWORD}@cluster0.ogm4i.mongodb.net/myFirstDatabase?retryWrites=true&w=majority`; // this can be copied in MongoDB Atlas mongoose .connect(uri, { useNewUrlParser: true, useUnifiedTopology: true, }); const db = mongoose.connection; db.on("err", (err) => { console.error(err); }); db.on("open", () => { console.log("Successfully connect to mongoDB"); }); ``` in `.env`: ``` MONGO_USERNAME= MONGO_PASSWORD= ``` Install `dotenv-defaults` if Error ``` npm install dotenv ``` #### Step 2: Define Schema Create a `model` directory In `user.js`: ```javascript= const mongoose = require("mongoose"); const Schema = mongoose.Schema; const UserSchema = new Schema({ id: { type: Number, required: [true, "Id field is required."], }, name: { type: String, required: [true, "Name field is required."], }, }); // Creating a table within database with the defined schema const User = mongoose.model("User", UserSchema); // Exporting table for querying and mutating module.exports = User; ``` In `server.js`: Import User Schema ```javascript= const User = require("./model/user"); ``` #### Step 3: Define Mutation Function In `server.js`: ```javascript= const saveUser = async (id, name) => { const existing = await User.findOne({ name: name }); if (existing) { console.log(`Username ${name} already exists!!`); return; } try { const newUser = new User({ id, name }); console.log("Created user", newUser); await newUser.save(); console.log("Successfully saved"); return; } catch (e) { throw new Error("User creation error: " + e); } }; const DeleteDB = async () => { try { await User.deleteMany({}); console.log("Database deleted"); } catch (e) { throw new Error("Database deletion failed"); } }; ``` :::info :book: Mutation: to mutate -> to modify data (CRUD operations) ::: #### Step 4: Define Route to call Mutation Functions In `server.js` ```javascript= const router = require("router"); router.post("/saveuser", saveUser) // More Routers app.use("/", router) ``` Or just ```javascript= app.route("/saveuser") .get((req, res) => { // do something }) ```