aboutsummaryrefslogtreecommitdiff
path: root/files/vi/learn/server-side
diff options
context:
space:
mode:
Diffstat (limited to 'files/vi/learn/server-side')
-rw-r--r--files/vi/learn/server-side/express_nodejs/development_environment/index.html407
-rw-r--r--files/vi/learn/server-side/express_nodejs/displaying_data/flow_control_using_async/index.html135
-rw-r--r--files/vi/learn/server-side/express_nodejs/displaying_data/index.html98
-rw-r--r--files/vi/learn/server-side/express_nodejs/index.html77
-rw-r--r--files/vi/learn/server-side/express_nodejs/mongoose/index.html800
-rw-r--r--files/vi/learn/server-side/express_nodejs/tutorial_local_library_website/index.html89
-rw-r--r--files/vi/learn/server-side/first_steps/index.html46
-rw-r--r--files/vi/learn/server-side/first_steps/introduction/index.html228
-rw-r--r--files/vi/learn/server-side/index.html59
9 files changed, 1939 insertions, 0 deletions
diff --git a/files/vi/learn/server-side/express_nodejs/development_environment/index.html b/files/vi/learn/server-side/express_nodejs/development_environment/index.html
new file mode 100644
index 0000000000..f46ebd1a9f
--- /dev/null
+++ b/files/vi/learn/server-side/express_nodejs/development_environment/index.html
@@ -0,0 +1,407 @@
+---
+title: Setting up a Node development environment
+slug: Learn/Server-side/Express_Nodejs/development_environment
+tags:
+ - Cài đặt
+ - Express
+ - Hướng dẫn
+ - hello world
+ - nodejs
+ - npm
+translation_of: Learn/Server-side/Express_Nodejs/development_environment
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/Introduction", "Learn/Server-side/Express_Nodejs/Tutorial_local_library_website", "Learn/Server-side/Express_Nodejs")}}</div>
+
+<p class="summary">Bây giờ bạn đã biết Express là gì, chúng tôi sẽ chỉ cho bạn cách cài đặt và kiểm tra một môi trường phát triển Node/Express trên Windows, Linux (Ubuntu) và macOS. Bất kể hệ điều hành bạn đang dùng là gì, bài này sẽ cho biết những thứ cần thiết để bắt đầu phát triển ứng dụng Express.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Điều kiện tiên quyết:</th>
+ <td>
+ <p>Biết mở Terminal / Command Prompt.<br>
+ Biết cài đặt các gói trên hệ điều hành của bạn.</p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Mục tiêu:</th>
+ <td>Cài đặt một môi trường phát triển cho Express (X.XX) trên máy tính của bạn.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Tổng_quan_môi_trường_phát_triển_Express">Tổng quan môi trường phát triển Express</h2>
+
+<p>Node và Express rất dễ dàng cài đặt trên máy tính của bạn để bắt đầu phát triển ứng dụng web. Mục này cho biết tổng quan về những công cụ nào cần dùng, giải thích một số phương pháp đơn giản nhất để cài Node (và Express) trên Ubuntu, macOS và Windows, kèm theo là hướng dẫn kiểm tra bạn đã cài được chưa.</p>
+
+<h3 id="Môi_trường_phát_triển_Express_là_gì">Môi trường phát triển Express là gì?</h3>
+
+<p>Môi trường phát triển Express bao gồm cài đặt <em>Nodejs, trình quản lý gói NPM</em> và (tuỳ chọn) <em>Express Application Generator (trình khởi tạo ứng dụng Express) </em>trên máy của bạn.</p>
+
+<p><em>Node</em> và <em>trình quản lý gói NPM</em> được cài đặt cùng nhau từ một gói, trình cài đặt, trình quản lý gói của hệ điều hành hoặc từ mã nguồn (xem các phần sau). <em>Express</em> được cài đặt sau đó bởi NPM như một phụ thuộc (dependency) của ứng dụng web <em>Express</em> (cùng với các thư viện khác như template engines, database drivers, authentication middleware, middleware to serve static files, v.v...).</p>
+
+<p><em>NPM</em> có thể được dùng để cài <em>Express Application Generator</em>, một công cụ tiện dụng để tạo bộ khung ứng dụng web Express theo <a href="https://developer.mozilla.org/en-US/Apps/Fundamentals/Modern_web_app_architecture/MVC_architecture">mô hình MVC</a>. Công cụ này là tuỳ chọn vì bạn không cần phải sử dụng nó để tạo ứng dụng Express. Tuy nhiên chúng tôi sẽ sử dụng, bởi vì nó giúp chúng ta bắt đầu dễ dàng hơn và cho chúng tâ cấu trúc ứng dụng dạng mô-đun.</p>
+
+<div class="note">
+<p><strong>Ghi chú:</strong> Không như một số web frameworks khác có môi trường phát triển không bao gồm một server rời. Trong <em>Node / Express</em>, một ứng dụng web tạo và chạy web server của nó!</p>
+</div>
+
+<p>Có những công cụ ngoại vi khác thường dùng trong môi trường phát triển bao gồm <a href="/en-US/docs/Learn/Common_questions/Available_text_editors">text editors</a> hoặc IDEs để chỉnh sửa code và công cụ quản lý mã nguồn như <a href="https://git-scm.com/">Git</a> để quản lý các phiên bản code khác nhau của bạn. Chúng tôi giả định bạn đã cài những công cụ này (đặc biệt là một text editor).</p>
+
+<h3 id="Những_hệ_điều_hành_nào_được_hỗ_trợ">Những hệ điều hành nào được hỗ trợ?</h3>
+
+<p>Node có thể chạy trên Windows, macOS, nhiều bản distro của Linux, Docker, v.v... (có danh sách đầy đủ ở <a href="https://nodejs.org/en/download/">Nodejs Downloads page</a>). Hầu hết mọi máy tính cá nhân đủ khả năng để chạy Node trong khi phát triển. Express chạy trong môi trường Node, do dó nó có thể chạy trên mọi nền tảng có Node.</p>
+
+<p>Trong bài này chúng tôi hướng dẫn cài đặt cho Windows, macOS và Ubuntu Linux.</p>
+
+<h3 id="Bạn_nên_sử_dụng_NodeExpress_phiên_bản_nào">Bạn nên sử dụng Node/Express phiên bản nào?</h3>
+
+<p>Có nhiều <a href="https://nodejs.org/en/blog/release/">phiên bản Node</a> — những bản mới được vá lỗi, hỗ trợ nhiều hơn cho các chuẩn ECMAScript (JavaScript) gần đây, và nâng cấp các Node APIs.</p>
+
+<p>Nhìn chung, bạn nên sử dụng bản<em> LTS (được hỗ trợ dài hạn)</em> mới nhất bởi vì nó ổn định hơn các các bản "current" mà vẫn có các tính năng tương đối mới gần đây (và vẫn được tích cực bảo trì). Bạn nên sử dụng phiên bản <em>Current</em> nếu bạn muốn dùng tính năng không có ở bản LTS.<br>
+ <br>
+ Với Express, bạn nên luôn sử dụng bản mới nhất.</p>
+
+<h3 id="Còn_cơ_sở_dữ_liệu_và_các_phụ_thuộc_khác_thì_sao">Còn cơ sở dữ liệu và các phụ thuộc khác thì sao?</h3>
+
+<p>Các phụ thuộc khác như database drivers, template engines, authentication engines, v.v.. là một phần của ứng dụng, được import vào môi trường ứng dụng bởi sử dụng trình quản lý gói NPM. Chúng tôi sẽ nói đến trong các bài cụ thể sau.</p>
+
+<h2 id="Cài_đặt_Node">Cài đặt Node</h2>
+
+<p>Để sử dụng <em>Express</em>, trước hết bạn phải cài <em>Nodejs</em> và <a href="https://docs.npmjs.com/">trình quản lý gói Node (NPM)</a> trên hệ điều hành của bạn. Những mục sau hướng dẫn cách đơn giản nhất để cài Nodejs phiên bản LTS trên Ubuntu Linux 16.04, macOS và Windows 10.</p>
+
+<div class="note">
+<p><strong>Mẹo:</strong> Những mục bên dưới hướng dẫn cách dễ nhất để cài Node và NPM trên các nền tảng OS của chúng tôi. Nếu bạn đang dùng OS khác hoặc muốn xem các cách khác để cài thì xem tại  <a href="https://nodejs.org/en/download/package-manager/">Installing Node.js via package manager</a> (nodejs.org).</p>
+</div>
+
+<h3 id="Windows_và_macOS">Windows và macOS</h3>
+
+<p>Cài đặt <em>Node</em> và <em>NPM</em> trên Windows và macOS đơn giản chỉ cần dùng trình cài đặt được cung cấp sẵn.</p>
+
+<ol>
+ <li>Tải trình cài đặt:
+ <ol>
+ <li>Truy cập <a href="https://nodejs.org/en/">https://nodejs.org/en/</a></li>
+ <li>Chọn nút tải xuống bản LTS.</li>
+ </ol>
+ </li>
+ <li>Click đúp chuột vào file đã tải và làm theo các hướng dẫn.</li>
+</ol>
+
+<h3 id="Ubuntu_16.04">Ubuntu 16.04</h3>
+
+<p>Cách đơn giản nhất để cài phiên bản LTS mới nhất của Node là sử dụng <a href="https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions">trình quản lý gói</a> để lấy từ Ubuntu <em>binary distributions</em> repository. Đơn giản là chạy hai câu lệnh sau trong terminal:</p>
+
+<pre class="brush: bash"><code>curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
+sudo apt-get install -y nodejs</code>
+</pre>
+
+<div class="warning">
+<p><strong>Lưu ý:</strong> Không cài trực tiếp từ normal Ubuntu repositories bởi vì các bản Node ở đó quá cũ.</p>
+</div>
+
+<ol>
+</ol>
+
+<h3 id="Kiểm_tra_kết_quả_cài_đặt">Kiểm tra kết quả cài đặt</h3>
+
+<p>Cách đơn giản nhất để kiểm tra xem node đã được cài chưa là chạy lệnh "version" trong terminal/ command prompt và xem phiên bản in ra:</p>
+
+<pre class="brush: bash">&gt;node -v
+v8.11.3</pre>
+
+<p>Trình quản lý gói Nodejs (NPM) cũng được cài đặt luôn, kiểm tra tương tự:</p>
+
+<pre class="brush: bash">&gt;npm -v
+5.8.0</pre>
+
+<p>Một bài kiểm tra thú vị hơn là tạo một server rất cơ bản "thuần Node" đơn giản in ra "Hello World" trong trình duyệt của bạn khi truy cập đúng URL:</p>
+
+<ol>
+ <li>Copy đoạn mã sau vào một file đặt tên là <strong>hellonode.js</strong>. Đoạn mã này sử dụng các tính năng <em>Node</em> thuần (không dùng gì của Express) và một vài cú pháp ES6:
+
+ <pre class="brush: js">//Load HTTP module
+const http = require("http");
+<code>const hostname = '127.0.0.1';
+const port = 3000;
+
+//Create HTTP server and listen on port 3000 for requests
+const server = http.createServer((req, res) =&gt; {
+
+  //Set the response HTTP header with HTTP status and Content type
+ res.statusCode = 200;
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('Hello World\n');
+});
+
+//listen for request on port 3000, and as a callback function have the port listened on logged
+server.listen(port, hostname, () =&gt; {
+ console.log(`Server running at http://${hostname}:${port}/`);
+});</code>
+
+</pre>
+
+ <p>Đoạn mã import mô-đun "http" và dùng nó để tạo một server (<code>createServer()</code>) lắng nghe HTTP request ở cổng 3000. Sau đó in ra một thông điệp về URL bạn có thể dùng để kiểm tra server. Hàm <code>createServer()</code> nhận tham số là một hàm callback được gọi khi nhận được một HTTP request — nó đơn giản trả về một response với HTTP status code 200 ("OK") và đoạn chữ "Hello World".</p>
+
+ <div class="note">
+ <p><strong>Ghi chú:</strong> Đừng lo lắng nếu bạn không hiểu chính xác việc mà đoạn code thực hiện. Chúng tôi sẽ giải thích rất chi tiết khi chúng ta bắt đầu sử dụng Express!</p>
+ </div>
+ </li>
+ <li>Khởi động server bằng cách điều hướng đến thư mục chứa <code>hellonode.js</code> trong terminal/ command prompt và gọi <code>node</code> với tên script, như sau:
+ <pre class="brush: bash">&gt;node hellonode.js
+Server running at http://127.0.0.1:3000/
+</pre>
+ </li>
+ <li>Truy cập vào URL <a href="http:127.0.0.1:3000">http://127.0.0.1:3000</a>. Nếu mọi thứ hoạt động, trình duyệt sẽ hiển thị dòng chữ "Hello World".</li>
+</ol>
+
+<h2 id="Using_NPM">Using NPM</h2>
+
+<p>Next to <em>Node</em> itself, <a href="https://docs.npmjs.com/">NPM</a> is the most important tool for working with<em> Node </em>applications. NPM is used to fetch any packages (JavaScript libraries) that an application needs for development, testing, and/or production, and may also be used to run tests and tools used in the development process. </p>
+
+<div class="note">
+<p><strong>Note:</strong> From Node's perspective, <em>Express</em> is just another package that you need to install using NPM and then require in your own code.</p>
+</div>
+
+<p>You can manually use NPM to separately fetch each needed package. Typically we instead manage dependencies using a plain-text definition file named <a href="https://docs.npmjs.com/files/package.json">package.json</a>. This file lists all the dependencies for a specific JavaScript "package", including the package's name, version, description, initial file to execute, production dependencies, development dependencies, versions of <em>Node</em> it can work with, etc. The <strong>package.json</strong> file should contain everything NPM needs to fetch and run your application (if you were writing a reusable library you could use this definition to upload your package to the npm respository and make it available for other users).</p>
+
+<h3 id="Adding_dependencies">Adding dependencies</h3>
+
+<p>The following steps show how you can use NPM to download a package, save it into the project dependencies, and then require it in a Node application.</p>
+
+<div class="note">
+<p><strong>Note:</strong> Here we show the instructions to fetch and install the <em>Express</em> package. Later on we'll show how this package, and others, are already specified for us using the <em>Express Application Generator</em>. This section is provided because it is useful to understand how NPM works and what is being created by the application generator.</p>
+</div>
+
+<ol>
+ <li>First create a directory for your new application and navigate into it:
+ <pre class="brush: bash">mkdir myapp
+cd myapp</pre>
+ </li>
+ <li>Use the npm <code>init</code> command to create a <strong>package.json</strong> file for your application. This command prompts you for a number of things, including the name and version of your application and the name of the initial entry point file (by default this is <strong>index.js</strong>). For now, just accept the defaults:
+ <pre class="brush: bash">npm init</pre>
+
+ <p>If you display the <strong>package.json</strong> file (<code>cat package.json</code>), you will see the defaults that you accepted, ending with the license.</p>
+
+ <pre class="brush: json">{
+ "name": "myapp",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" &amp;&amp; exit 1"
+ },
+ "author": "",
+ "license": "ISC"
+}
+</pre>
+ </li>
+ <li>Now install Express in the <code>myapp</code> directory and save it in the dependencies list of your package.json file</li>
+ <li>
+ <pre class="brush: bash">npm install express --save</pre>
+
+ <p>The dependencies section of your <strong>package.json</strong> will now appear at the end of the <strong>package.json</strong> file and will include <em>Express</em>.</p>
+
+ <pre class="brush: json">{
+ "name": "myapp",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" &amp;&amp; exit 1"
+ },
+ "author": "",
+ "license": "ISC",
+<strong> "dependencies": {
+ "express": "^4.16.3"
+ }</strong>
+}
+</pre>
+ </li>
+ <li>To use the library you call the <code>require()</code> function as shown below in your index.js file.
+ <pre><code><strong>const express = require('express')</strong>
+const app = express();
+
+app.get('/', (req, res) =&gt; {
+ res.send('Hello World!')
+});
+
+app.listen(</code>8000<code>, () =&gt; {
+ console.log('Example app listening on port </code>8000<code>!')
+});</code>
+</pre>
+
+ <p>This code shows a minimal "HelloWorld" Express web application. This imports the "express" module and uses it to create a server (<code>app</code>) that listens for HTTP requests on port 8000 and prints a message to the console explaining what browser URL you can use to test the server. The <code>app.get()</code> function only responds to HTTP <code>GET</code> requests with the specified URL path ('/'), in this case by calling a function to send our <em>Hello World!</em> message. <br>
+ <br>
+ Create a file named <strong>index.js</strong> in the root of the "myapp" application directory and give it the contents shown above.</p>
+ </li>
+ <li>You can start the server by calling node with the script in your command prompt:
+ <pre class="brush: bash">&gt;node index.js
+Example app listening on port 8000
+</pre>
+ </li>
+ <li>Navigate to the URL (<a href="http://127.0.0.1:8000/">http://127.0.0.1:8000/</a>). If everything is working, the browser should simply display the string "Hello World!".</li>
+</ol>
+
+<h3 id="Development_dependencies">Development dependencies</h3>
+
+<p>If a dependency is only used during development, you should instead save it as a "development dependency" (so that your package users don't have to install it in production). For example, to use the popular JavaScript Linting tool <a href="http://eslint.org/">eslint</a> you would call NPM as shown:</p>
+
+<pre class="brush: bash"><code>npm install eslint --save-dev</code></pre>
+
+<p>The following entry would then be added to your application's <strong>package.json</strong>:</p>
+
+<pre class="brush: js"> "devDependencies": {
+ "eslint": "^4.12.1"
+ }
+</pre>
+
+<div class="note">
+<p><strong>Note:</strong> "<a href="https://en.wikipedia.org/wiki/Lint_(software)">Linters</a>" are tools that perform static analysis on software in order to recognise and report adherence/non-adherance to some set of coding best practice.</p>
+</div>
+
+<h3 id="Running_tasks">Running tasks</h3>
+
+<p>In addition to defining and fetching dependencies you can also define <em>named</em> scripts in your <strong>package.json</strong> files and call NPM to execute them with the <a href="https://docs.npmjs.com/cli/run-script">run-script</a> command. This approach is commonly used to automate running tests and parts of the development or build toolchain (e.g., running tools to minify JavaScript, shrink images, LINT/analyse your code, etc).</p>
+
+<div class="note">
+<p><strong>Note:</strong> Task runners like <a href="http://gulpjs.com/">Gulp</a> and <a href="http://gruntjs.com/">Grunt</a> can also be used to run tests and other external tools.</p>
+</div>
+
+<p>For example, to define a script to run the <em>eslint</em> development dependency that we specified in the previous section we might add the following script block to our <strong>package.json</strong> file (assuming that our application source is in a folder /src/js):</p>
+
+<pre class="brush: js">"scripts": {
+ ...
+ "lint": "eslint src/js"
+  ...
+}
+</pre>
+
+<p>To explain a little further, <code>eslint src/js</code> is a command that we could enter in our terminal/command line to run <code>eslint</code> on JavaScript files contained in the <code>src/js</code> directory inside our app directory. Including the above inside our app's package.json file provides a shortcut for this command — <code>lint</code>.</p>
+
+<p>We would then be able to run <em>eslint</em> using NPM by calling:</p>
+
+<pre class="brush: bash"><code>npm run-script lint
+# OR (using the alias)
+npm run lint</code>
+</pre>
+
+<p>This example may not look any shorter than the original command, but you can include much bigger commands inside your npm scripts, including chains of multiple commands. You could identify a single npm script that runs all your tests at once.</p>
+
+<h2 id="Installing_the_Express_Application_Generator">Installing the Express Application Generator</h2>
+
+<p>The <a href="https://expressjs.com/en/starter/generator.html">Express Application Generator</a> tool generates an Express application "skeleton". Install the generator using NPM as shown (the <code>-g</code> flag installs the tool globally so that you can call it from anywhere):</p>
+
+<pre><code>npm install express-generator -g</code></pre>
+
+<p>To create an <em>Express</em> app named "helloworld" with the default settings, navigate to where you want to create it and run the app as shown:</p>
+
+<pre class="brush: bash">express helloworld</pre>
+
+<div class="note">
+<p><strong>Note: </strong>You can also specify the template library to use and a number of other settings. Use the <code>help</code> command to see all the options:</p>
+
+<pre class="brush: bash">express --help
+</pre>
+
+<p> </p>
+</div>
+
+<p>NPM will create the new Express app in a sub folder of your current location, displaying build progress on the console. On completion, the tool will display the commands you need to enter to install the Node dependencies and start the app.</p>
+
+<div class="note">
+<p>The new app will have a <strong>package.json</strong> file in its root directory. You can open this to see what dependencies are installed, including Express and the template library Jade:</p>
+
+<pre class="brush: js">{
+  "name": "helloworld",
+  "version": "0.0.0",
+  "private": true,
+  "scripts": {
+    "start": "node ./bin/www"
+  },
+  "dependencies": {
+    "body-parser": "~1.18.2",
+    "cookie-parser": "~1.4.3",
+    "debug": "~2.6.9",
+    "express": "~4.15.5",
+    "jade": "~1.11.0",
+    "morgan": "~1.9.0",
+    "serve-favicon": "~2.4.5"
+  }
+}</pre>
+
+<p> </p>
+</div>
+
+<p>Install all the dependencies for the helloworld app using NPM as shown:</p>
+
+<pre class="brush: bash">cd helloworld
+npm install
+</pre>
+
+<p>Then run the app (the commands are slightly different for Windows and Linux/macOS), as shown below:</p>
+
+<pre class="brush: bash"># Run the helloworld on Windows with Command Prompt
+SET DEBUG=helloworld:* &amp; npm start
+
+# Run the helloworld on Windows with PowerShell
+SET DEBUG=helloworld:* | npm start
+
+# Run helloworld on Linux/macOS
+DEBUG=helloworld:* npm start
+</pre>
+
+<p>The DEBUG command creates useful logging, resulting in an output like that shown below.</p>
+
+<pre class="brush: bash">&gt;SET DEBUG=helloworld:* &amp; npm start
+
+&gt; helloworld@0.0.0 start D:\Github\expresstests\helloworld
+&gt; node ./bin/www
+
+  helloworld:server Listening on port 3000 +0ms</pre>
+
+<p>Open a browser and navigate to <a href="http://127.0.0.1:3000/">http://127.0.0.1:3000/</a> to see the default Express welcome page.</p>
+
+<p><img alt="Express - Generated App Default Screen" src="https://mdn.mozillademos.org/files/14331/express_default_screen.png" style="border-style: solid; border-width: 1px; display: block; height: 301px; margin: 0px auto; width: 675px;"></p>
+
+<p>We'll talk more about the generated app when we get to the article on generating a skeleton application.</p>
+
+<ul>
+</ul>
+
+<h2 id="Summary">Summary</h2>
+
+<p>You now have a Node development environment up and running on your computer that can be used for creating Express web applications. You've also seen how NPM can be used to import Express into an application, and also how you can create applications using the Express Application Generator tool and then run them.</p>
+
+<p>In the next article we start working through a tutorial to build a complete web application using this environment and associated tools.</p>
+
+<h2 id="See_also">See also</h2>
+
+<ul>
+ <li><a href="https://nodejs.org/en/download/">Downloads</a> page (nodejs.org)</li>
+ <li><a href="https://nodejs.org/en/download/package-manager/">Installing Node.js via package manager</a> (nodejs.org)</li>
+ <li><a href="http://expressjs.com/en/starter/installing.html">Installing Express</a> (expressjs.com)</li>
+ <li><a href="https://expressjs.com/en/starter/generator.html">Express Application Generator</a> (expressjs.com)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/Introduction", "Learn/Server-side/Express_Nodejs/Tutorial_local_library_website", "Learn/Server-side/Express_Nodejs")}}</p>
+
+<p> </p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Introduction">Express/Node introduction</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/development_environment">Setting up a Node (Express) development environment</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">Express Tutorial: The Local Library website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/skeleton_website">Express Tutorial Part 2: Creating a skeleton website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose">Express Tutorial Part 3: Using a Database (with Mongoose)</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/routes">Express Tutorial Part 4: Routes and controllers</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data">Express Tutorial Part 5: Displaying library data</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/forms">Express Tutorial Part 6: Working with forms</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/deployment">Express Tutorial Part 7: Deploying to production</a></li>
+</ul>
+
+<p> </p>
diff --git a/files/vi/learn/server-side/express_nodejs/displaying_data/flow_control_using_async/index.html b/files/vi/learn/server-side/express_nodejs/displaying_data/flow_control_using_async/index.html
new file mode 100644
index 0000000000..6d5192d404
--- /dev/null
+++ b/files/vi/learn/server-side/express_nodejs/displaying_data/flow_control_using_async/index.html
@@ -0,0 +1,135 @@
+---
+title: Kiểm soát luồng không đồng bộ bằng cách sử dụng async
+slug: Learn/Server-side/Express_Nodejs/Displaying_data/flow_control_using_async
+translation_of: Learn/Server-side/Express_Nodejs/Displaying_data/flow_control_using_async
+---
+<p>Mã điều khiển cho một số trang <em>LocalLibrary</em> của chúng tôi sẽ phụ thuộc vào kết quả của nhiều yêu cầu bất đồng bộ, có thể được yêu cầu chạy theo một số thứ tự cụ thể hoặc song song. Để quản lý kiểm soát dòng chảy, và đưa ra trang khi chúng tôi có tất cả các thông tin cần thiết có sẵn, chúng tôi sẽ sử dụng các nút phổ biến <a class="external external-icon" href="https://www.npmjs.com/package/async" rel="noopener">async</a> module.</p>
+
+<div class="note">
+<p><strong>Lưu ý:</strong> Có một số cách khác để quản lý hành vi bất đồng bộ và kiểm soát luồng trong JavaScript, bao gồm các tính năng ngôn ngữ JavaScript tương đối gần đây như <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/Techniques/Promises">Promises</a>.</p>
+</div>
+
+<p>Async có rất nhiều phương pháp hữu ích (xem <a class="external external-icon" href="http://caolan.github.io/async/docs.html" rel="noopener">tài liệu</a> ). Một số chức năng quan trọng hơn là:</p>
+
+<ul>
+ <li><code><a class="external external-icon" href="http://caolan.github.io/async/docs.html#parallel" rel="noopener">async.parallel()</a></code> để thực hiện bất kỳ thao tác nào phải được thực hiện song song.</li>
+ <li><code><a class="external external-icon" href="http://caolan.github.io/async/docs.html#series" rel="noopener">async.series()</a></code> khi chúng ta cần đảm bảo rằng các hoạt động bất đồng bộ được thực hiện theo chuỗi.</li>
+ <li><code><a class="external external-icon" href="http://caolan.github.io/async/docs.html#waterfall" rel="noopener">async.waterfall()</a></code> cho các hoạt động phải được chạy theo chuỗi, với mỗi thao tác tùy thuộc vào kết quả của các phép toán trước đó.</li>
+</ul>
+
+<h2 id="Tại_sao_nó_cần_thiết">Tại sao nó cần thiết?</h2>
+
+<p>Hầu hết các phương thức chúng tôi sử dụng trong <em>Express</em> đều bất đồng bộ — bạn chỉ định một thao tác để thực hiện, chuyển một cuộc gọi lại. Phương thức trả về ngay lập tức và gọi lại được gọi khi hoạt động được yêu cầu hoàn tất. Theo quy ước trong <em>Express</em> , hàm gọi lại truyền giá trị <em>lỗi</em> làm tham số đầu tiên (hoặc <code>null</code>thành công) và kết quả từ hàm (nếu có) làm tham số thứ hai.</p>
+
+<p>Nếu một bộ điều khiển chỉ cần <em>thực hiện <strong>một</strong> thao tác bất đồng bộ</em> để có được thông tin cần thiết để hiển thị một trang thì việc triển khai thực hiện rất dễ dàng — chúng tôi chỉ cần hiển thị mẫu trong cuộc gọi lại. Đoạn mã dưới đây cho thấy điều này cho một hàm làm cho số đếm của một mô hình <code>SomeModel</code>(sử dụng <code><a class="external external-icon" href="http://mongoosejs.com/docs/api.html#model_Model.count" rel="noopener">count()</a></code>phương thức Mongoose ):</p>
+
+<pre class="brush: js"><code>exports.some_model_count = function(req, res, next) {
+
+</code> SomeModel.count ({a_model_field: 'match_value'}, hàm (err, count) {
+ // ... làm gì đó nếu có lỗi
+
+  // Khi thành công, trả kết quả bằng cách chuyển số đếm vào hàm render (ở đây, dưới dạng biến 'data').
+  res.render ('the_template', {data: count});
+  });
+<code>}</code>
+</pre>
+
+<p>Tuy nhiên, nếu bạn cần thực hiện <strong>nhiều</strong> truy vấn bất đồng bộ và bạn không thể hiển thị trang cho đến khi tất cả các thao tác đã hoàn tất? Việc triển khai ngây thơ có thể "chuỗi daisy" các yêu cầu, khởi động các yêu cầu tiếp theo trong cuộc gọi lại của yêu cầu trước đó và hiển thị phản hồi trong cuộc gọi lại cuối cùng. Vấn đề với cách tiếp cận này là các yêu cầu của chúng tôi sẽ phải được chạy theo chuỗi, mặc dù nó có thể hiệu quả hơn để chạy chúng song song. Điều này cũng có thể dẫn đến mã lồng nhau phức tạp, thường được gọi là <a class="external external-icon" href="http://callbackhell.com/" rel="noopener">địa chỉ gọi lại</a> (<strong>callback hell</strong>) .</p>
+
+<p>Một giải pháp tốt hơn sẽ là thực hiện tất cả các yêu cầu song song và sau đó có một cuộc gọi lại duy nhất thực hiện khi tất cả các truy vấn đã hoàn thành. Đây là loại hoạt động lưu lượng mà mô-đun <em>Async</em> làm cho dễ dàng!</p>
+
+<h2 id="Hoạt_động_bất_đồng_bộ_song_song">Hoạt động bất đồng bộ song song</h2>
+
+<p>Phương pháp <code><a class="external external-icon" href="http://caolan.github.io/async/docs.html#parallel" rel="noopener">async.parallel()</a></code>này được sử dụng để chạy nhiều hoạt động bất đồng bộ song song.</p>
+
+<p>Đối số đầu tiên <code>async.parallel()</code>là một tập hợp các hàm bất đồng bộ để chạy (một mảng, đối tượng hoặc có thể lặp lại khác). Mỗi chức năng được truyền <code>callback(err, result)</code>mà nó phải gọi khi hoàn thành với một lỗi <code>err</code>(có thể là <code>null</code>) và một <code>results</code>giá trị tùy chọn .</p>
+
+<p>Đối số thứ hai tùy chọn  <code>async.parallel()</code>là một cuộc gọi lại sẽ được chạy khi tất cả các hàm trong đối số đầu tiên đã hoàn thành. Gọi lại được gọi với một đối số lỗi và một bộ sưu tập kết quả có chứa các kết quả của các hoạt động bất đồng bộ riêng lẻ. Bộ sưu tập kết quả có cùng kiểu với đối số đầu tiên (tức là nếu bạn truyền một mảng các hàm bất đồng bộ, thì hàm gọi lại cuối cùng sẽ được gọi với một mảng các kết quả). Nếu bất kỳ hàm song song nào báo cáo lỗi thì gọi lại được gọi sớm (với giá trị lỗi).</p>
+
+<p>Ví dụ dưới đây cho thấy cách thức này hoạt động khi chúng ta truyền một đối tượng làm đối số đầu tiên. Như bạn có thể thấy, các kết quả được <em>trả về</em> trong một đối tượng có cùng tên thuộc tính như các hàm ban đầu được truyền vào.</p>
+
+<pre class="brush: js line-numbers language-js"><code class="language-js">async.parallel({
+ one: function(callback) { ... },
+ two: function(callback) { ... },
+ ...
+ something_else: function(callback) { ... }
+ },
+ // optional callback
+ function(err, results) {
+ // 'results' is now equal to: {one: 1, two: 2, ..., something_else: some_value}
+ }
+);</code></pre>
+
+<p>Nếu bạn thay vì truyền một mảng các hàm như đối số đầu tiên, kết quả sẽ là một mảng (kết quả thứ tự mảng sẽ khớp với thứ tự ban đầu mà các hàm được khai báo — không phải thứ tự mà chúng đã hoàn thành).</p>
+
+<h2 id="Các_hoạt_động_bất_đồng_bộ_trong_chuỗi">Các hoạt động bất đồng bộ trong chuỗi</h2>
+
+<p>Phương thức <code><a class="external external-icon" href="http://caolan.github.io/async/docs.html#series" rel="noopener">async.series()</a></code>này được sử dụng để chạy nhiều hoạt động bất đồng bộ theo thứ tự, khi các hàm tiếp theo không phụ thuộc vào đầu ra của các hàm trước đó. Nó cơ bản được khai báo và cư xử theo cùng một cách như <code>async.parallel()</code>.</p>
+
+<pre class="brush: js line-numbers language-js"><code class="language-js">async.series({
+ one: function(callback) { ... },
+ two: function(callback) { ... },
+ ...
+ something_else: function(callback) { ... }
+ },
+ // optional callback after the last asynchronous function completes.
+ function(err, results) {
+ // 'results' is now equals to: {one: 1, two: 2, ..., something_else: some_value}
+ }
+);</code></pre>
+
+<div class="note">
+<p><strong>Lưu ý:</strong> Đặc tả ngôn ngữ ECMAScript (JavaScript) nói rằng thứ tự liệt kê một đối tượng là không xác định, vì vậy có thể các hàm sẽ không được gọi theo cùng thứ tự như bạn chỉ định chúng trên tất cả các nền tảng. Nếu thứ tự thực sự quan trọng, thì bạn nên chuyển một mảng thay vì một đối tượng, như hình dưới đây.</p>
+</div>
+
+<pre class="brush: js line-numbers language-js"><code class="language-js">async.series([
+ function(callback) {
+ // do some stuff ...
+ callback(null, 'one');
+ },
+ function(callback) {
+ // do some more stuff ...
+ callback(null, 'two');
+ }
+ ],
+ // optional callback
+ function(err, results) {
+ // results is now equal to ['one', 'two']
+ }
+);</code></pre>
+
+<h2 id="Các_hoạt_động_bất_đồng_bộ_phụ_thuộc_trong_chuỗi">Các hoạt động bất đồng bộ phụ thuộc trong chuỗi</h2>
+
+<p>Phương thức <code><a class="external external-icon" href="http://caolan.github.io/async/docs.html#waterfall" rel="noopener">async.waterfall()</a></code>này được sử dụng để chạy nhiều hoạt động bất đồng bộ theo thứ tự khi mỗi hoạt động phụ thuộc vào kết quả của hoạt động trước đó.</p>
+
+<p>Hàm gọi lại được gọi bởi mỗi hàm bất đồng bộ chứa <code>null</code>đối số đầu tiên và kết quả trong các đối số tiếp theo. Mỗi hàm trong chuỗi lấy các đối số kết quả của lần gọi lại trước đó làm tham số đầu tiên, và sau đó là một hàm gọi lại. Khi tất cả các hoạt động được hoàn thành, một cuộc gọi lại cuối cùng được gọi với kết quả của hoạt động cuối cùng. Cách làm việc này là rõ ràng hơn khi bạn xem xét các đoạn mã dưới đây (ví dụ này là từ <em>async</em> tài liệu):</p>
+
+<pre class="brush: js line-numbers language-js"><code class="language-js">async.waterfall([
+ function(callback) {
+ callback(null, 'one', 'two');
+ },
+ function(arg1, arg2, callback) {
+ // arg1 now equals 'one' and arg2 now equals 'two'
+ callback(null, 'three');
+ },
+ function(arg1, callback) {
+ // arg1 now equals 'three'
+ callback(null, 'done');
+ }
+], function (err, result) {
+ // result now equals 'done'
+}
+);</code></pre>
+
+<h2 id="Cài_đặt_bất_đồng_bộ">Cài đặt bất đồng bộ</h2>
+
+<p>Cài đặt mô-đun bất đồng bộ bằng cách sử dụng trình quản lý gói NPM để chúng tôi có thể sử dụng nó trong mã của chúng tôi. Bạn làm điều này theo cách thông thường, bằng cách mở một dấu nhắc trong thư mục gốc của dự án <em>LocalLibrary</em> và nhập vào lệnh sau đây:</p>
+
+<pre class="brush: bash line-numbers language-bash"><code class="language-bash">npm install async</code></pre>
+
+<h2 id="Bước_tiếp_theo">Bước tiếp theo</h2>
+
+<ul>
+ <li>Quay lại  <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data">Hướng dẫn Express Phần 5: Hiển thị dữ liệu thư viện</a> .</li>
+ <li>Chuyển đến phần con tiếp theo của Phần 5: <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Template_primer">Mẫu mồi</a> .</li>
+</ul>
diff --git a/files/vi/learn/server-side/express_nodejs/displaying_data/index.html b/files/vi/learn/server-side/express_nodejs/displaying_data/index.html
new file mode 100644
index 0000000000..bdbf433fc3
--- /dev/null
+++ b/files/vi/learn/server-side/express_nodejs/displaying_data/index.html
@@ -0,0 +1,98 @@
+---
+title: 'Express Tutorial Part 5: Displaying library data'
+slug: Learn/Server-side/Express_Nodejs/Displaying_data
+tags:
+ - Beginner
+ - Controller
+ - Express
+ - Learn
+ - NeedsTranslation
+ - Template
+ - TopicStub
+ - View
+ - nodejs
+ - pug
+translation_of: Learn/Server-side/Express_Nodejs/Displaying_data
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/routes", "Learn/Server-side/Express_Nodejs/forms", "Learn/Server-side/Express_Nodejs")}}</div>
+
+<p class="summary">We're now ready to add the pages that display the <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">LocalLibrary</a> website books and other data. The pages will include a home page that shows how many records we have of each model type, and list and detail pages for all of our models. Along the way we'll gain practical experience in getting records from the database, and using templates.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prerequisites:</th>
+ <td>Complete previous tutorial topics (including <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/routes">Express Tutorial Part 4: Routes and controllers</a>).</td>
+ </tr>
+ <tr>
+ <th scope="row">Objective:</th>
+ <td>To understand how to use the async module and Pug template language, and how to get data from the URL in our controller functions.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Overview">Overview</h2>
+
+<p>In our previous tutorial articles we defined <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose">Mongoose models</a> that we can use to interact with a database and created some initial library records. We then <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/routes">created all the routes</a> needed for the LocalLibrary website, but with "dummy controller" functions (these are skeleton controller functions that just return a "not implemented" message when a page is accessed).</p>
+
+<p>The next step is to provide proper implementations for the pages that <em>display</em> our library information (we'll look at implementing pages featuring forms to create, update, or delete information in later articles). This includes updating the controller functions to fetch records using our models, and defining templates to display this information to users.</p>
+
+<p>We will start by providing overview/primer topics explaining how to manage asynchronous operations in controller functions and how to write templates using Pug. Then we'll provide implementations for each of our main "read only" pages with a brief explanation of any special or new features that they use.</p>
+
+<p>At the end of this article you should have a good end-to-end understanding of how routes, asynchronous functions, views, and models work in practice.</p>
+
+<h2 id="Displaying_library_data_tutorial_subarticles">Displaying library data tutorial subarticles</h2>
+
+<p>The following subarticles go through the process of adding the different features required for us to display the required website pages. You need to read and work through each one of these in turn, before moving on to the next one.</p>
+
+<ol>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/flow_control_using_async">Asynchronous flow control using async</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Template_primer">Template primer</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/LocalLibrary_base_template">The LocalLibrary base template</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Home_page">Home page</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Book_list_page">Book list page</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/BookInstance_list_page">BookInstance list page</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Date_formatting_using_moment">Date formatting using moment</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Author_list_page">Author list page and Genre list page challenge</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Genre_detail_page">Genre detail page</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Book_detail_page">Book detail page</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Author_detail_page">Author detail page</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/BookInstance_detail_page_and_challenge">BookInstance detail page and challenge</a></li>
+</ol>
+
+<h2 id="Summary">Summary</h2>
+
+<p>We've now created all the "read-only" pages for our site: a home page that displays counts of instances of each of our models, and list and detail pages for our books, book instances, authors, and genres. Along the way we've gained a lot of fundamental knowledge about controllers, managing flow control when using asynchronous operations, creating views using <em>Pug</em>, querying the database using our models, how to pass information to a template from your view, and how to create and extend templates. Those who completed the challenge will also have learned a little about date handling using <em>moment</em>.</p>
+
+<p>In our next article we'll build on our knowledge, creating HTML forms and form handling code to start modifying the data stored by the site.</p>
+
+<h2 id="See_also">See also</h2>
+
+<ul>
+ <li><a href="http://caolan.github.io/async/docs.html">Async module</a> (Async docs)</li>
+ <li><a href="https://expressjs.com/en/guide/using-template-engines.html">Using Template engines with Express</a> (Express docs)</li>
+ <li><a href="https://pugjs.org/api/getting-started.html">Pug</a> (Pug docs)</li>
+ <li><a href="http://momentjs.com/docs/">Moment</a> (Moment docs)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/routes", "Learn/Server-side/Express_Nodejs/forms", "Learn/Server-side/Express_Nodejs")}}</p>
+
+<p> </p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Introduction">Express/Node introduction</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/development_environment">Setting up a Node (Express) development environment</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">Express Tutorial: The Local Library website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/skeleton_website">Express Tutorial Part 2: Creating a skeleton website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose">Express Tutorial Part 3: Using a Database (with Mongoose)</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/routes">Express Tutorial Part 4: Routes and controllers</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data">Express Tutorial Part 5: Displaying library data</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/forms">Express Tutorial Part 6: Working with forms</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/deployment">Express Tutorial Part 7: Deploying to production</a></li>
+</ul>
+
+<p> </p>
diff --git a/files/vi/learn/server-side/express_nodejs/index.html b/files/vi/learn/server-side/express_nodejs/index.html
new file mode 100644
index 0000000000..8cdfa86487
--- /dev/null
+++ b/files/vi/learn/server-side/express_nodejs/index.html
@@ -0,0 +1,77 @@
+---
+title: Express web framework (Node.js/JavaScript)
+slug: Learn/Server-side/Express_Nodejs
+tags:
+ - Beginner
+ - CodingScripting
+ - Express
+ - Express.js
+ - Intro
+ - JavaScript
+ - Learn
+ - NeedsTranslation
+ - Node
+ - Server-side programming
+ - TopicStub
+ - node.js
+translation_of: Learn/Server-side/Express_Nodejs
+---
+<div>{{LearnSidebar}}</div>
+
+<p class="summary">Express là một web framework phổ biến, được viết bằng JavaScript và chạy trên môi trường Node.js. Mô-đun sẽ giải thích một số lợi ích của framework này, cách để thiết lập môi trường, phát triển cũng như triển khai ứng dụng.</p>
+
+<h2 id="Điều_kiện_tiên_quyết">Điều kiện tiên quyết</h2>
+
+<p>Trước khi bắt đầu với module này, bạn cần có kiến thức về lập trình web phía máy chủ và web framework là gì, bạn có thể đọc: <a href="/en-US/docs/Learn/Server-side/First_steps">Những bước đầu về lập trình web phía máy chủ</a>. Bạn cũng cần có kiến thức tổng quát về ngôn ngữ lập trình và đặc biệt là <a href="/en-US/docs/Web/JavaScript">JavaScript</a>, nhưng không quá quan trọng để hiểu những khái niệm cốt lõi.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Những trang web có nhiều tài nguyên để học JavaScript<em> về phát triển ở phía client (khách)</em>: <a href="/en-US/docs/Web/JavaScript">JavaScript</a>, <a href="/en-US/docs/Web/JavaScript/Guide">JavaScript Guide</a>, <a href="/en-US/docs/Learn/Getting_started_with_the_web/JavaScript_basics">JavaScript Basics</a>, <a href="/en-US/docs/Learn/JavaScript">JavaScript</a> (learning). Những khái niệm cốt lõi và ngôn ngữ JavaScript là tương tự với phát triển ở phía server (chủ) trên Node.js và tài liệu này sẽ đề cập. Node.js cung cấp các <a href="https://nodejs.org/dist/latest-v6.x/docs/api/">APIs bổ sung</a> để hỗ trợ các chức năng hữu ích trong môi trường không có trình duyệt, ví dụ: tạo các máy chủ HTTP và truy cập hệ thống tệp, nhưng không hỗ trợ các JavaScript APIs để làm việc với trình duyệt và DOM.</p>
+
+<p>Hướng dẫn này sẽ cung cấp một số kiến thức khi làm việc với Node.js và Express, có vô số tài nguyên tuyệt vời khác trên Internet và trong sách — vài trong số đó đến từ <a href="http://stackoverflow.com/a/5511507/894359">How do I get started with Node.js</a> (StackOverflow) và <a href="https://www.quora.com/What-are-the-best-resources-for-learning-Node-js?">What are the best resources for learning Node.js?</a> (Quora).</p>
+</div>
+
+<h2 id="Hướng_Dẫn">Hướng Dẫn</h2>
+
+<dl>
+ <dt><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/Introduction">Giới thiệu Express/Node</a></dt>
+ <dd>Trong bài viết đầu tiên về Express, chúng ta trả lời câu hỏi "Node là gì?" và "Express là gì?" và cho bạn một cái nhìn tổng quan về thứ làm nên sự đặc biệt của Express web framework. Chúng ta sẽ điểm qua các tính năng chính và cho bạn thấy những thành phần dựng nên một ứng dụng Express (mặc dù hiện tại bạn chưa có môi trường phát triển để thử nó).</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/development_environment">Cài đặt một môi trường phát triển Node (Express)</a></dt>
+ <dd>Bây giờ bạn đã biết Express là gì, chúng ta sẽ xem cách để cài đặt một môi trường Node/Express trên Windows, Linux (Ubuntu), và macOS. Bất kỳ hệ điều hành phổ biến nào bạn đang sử dụng, bài viết này sẽ cho bạn những thứ cần thiết để có thể bắt đầu phát triển ứng dụng Express.</dd>
+ <dt><a href="/vi/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">Hướng dẫn Express: Trang web Local Library</a></dt>
+ <dd>Bài đầu tiên trong chuỗi hướng dẫn thực hành giải thích những gì bạn sẽ học, và tổng quan về ví dụ trang web "local library" mà chúng ta sẽ làm việc và phát triển trong các bài tiếp theo.</dd>
+ <dt><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/skeleton_website">Hướng dẫn Express Phần 2: Tạo cấu trúc cho dự án</a></dt>
+ <dd>Bài này hướng dẫn bạn cách tạo một "bộ khung" cho dự án web, là nơi để bạn tiếp tục phát triển định tuyến (routes) cho các trang, templates/views và cơ sở dữ liệu.</dd>
+ <dt><a href="https://developer.mozilla.org/vi/docs/Learn/Server-side/Express_Nodejs/mongoose">Hướng dẫn Express Phần 3: Sử dụng cơ sở dữ liệu (với Mongoose)</a></dt>
+ <dd>Bài này giới thiệu tóm tắt về cơ sở dữ liệu cho Node/Express. Sau đó là cách chúng ta sử dụng <a href="http://mongoosejs.com/">Mongoose</a> để truy cập cơ sở dữ liệu cho trang web <em>LocalLibrary</em>. Bài viết giải thích cách lược đồ đối tượng và các mô hình được khai báo, các trường chính và xác thực cơ bản, cũng như cho biết một số cách chính để truy cập dữ liệu mô hình.</dd>
+ <dt><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/routes">Hướng dẫn Express Phần 4: Routes và controllers</a></dt>
+ <dd>Trong phần này chúng ta sẽ thiếp lập định tuyến (code xử lý URL) với các hàm xử lý "?giả" cho các tài nguyên cần thiết trong trang web <em>LocalLibrary</em>. Khi hoàn thành, chúng ta sẽ có một cấu trúc mô-đun để đặt code xử lý định tuyến, sau đó có thể mở rộng bằng các hàm xử lý thật ở các bài sau. Từ đó chúng ta có được hiểu biết tốt về cách tạo mô-đun định tuyến sử dụng Express.</dd>
+ <dt><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data">Hướng dẫn Express Phần 5: Hiển thị dữ liệu thư viện</a></dt>
+ <dd>Bây giờ chúng ta đã sẵn sàng để thêm các trang hiển thị sách và dữ liệu của trang web <em>LocalLibrary</em>. Những trang này gồm một trang chủ để xem có bao nhiêu bản ghi trên mỗi loại mô hình, các trang xem danh sách, chi tiết cho tất cả các mô hình. Chúng ta sẽ thực hành theo cách lấy các bản ghi từ cơ sở dữ liệu và dùng các bản mẫu (templates).</dd>
+ <dt><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/forms">Hướng dẫn Express Phần 6: Làm việc với forms</a></dt>
+ <dd>Trong bài này chúng ta sẽ xem cách làm việc với <a href="/en-US/docs/Web/Guide/HTML/Forms">HTML Forms</a> trong Express, sử dụng Pug và cách để viết form tạo, cập nhật, xoá tài liệu từ cơ sở dữ liệu.</dd>
+ <dt><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/deployment">Hướng dẫn Express Phần 7: Triển khai sử dụng</a></dt>
+ <dd>Bây giờ bạn đã tạo xong trang web <em>LocalLibrary</em> tuyệt vời, bạn sẽ muốn cài đặt nó lên một máy chủ public để các nhân viên thư viện và các thành viên có thể truy cập được từ Internet. Bài này cung cấp tổng quan về cách làm sao để bạn có thể tìm một máy chủ để triển khai trang web của bạn và những gì bạn cần để giúp trang web sẵn sàng sử dụng.</dd>
+</dl>
+
+<h2 id="Xem_thêm">Xem thêm</h2>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Installing_on_PWS_Cloud_Foundry">Cài đặt LocalLibrary trên PWS/Cloud Foundry</a></dt>
+ <dd>Bài này cung cấp một minh họa thực tế cách để cài đặt <em>LocalLibrary</em> trên <a href="http://run.pivotal.io">Pivotal Web Services PaaS cloud</a> — một dịch vụ nguồn mở với đầy đủ tính năng thay thế cho Heroku, dịch vụ cloud PaaS đã sử dụng ở Phần 7 của hướng dẫn bên trên. PWS/Cloud Foundry chắc chắn đáng giá để dùng nếu bạn đang tìm một sự thay thế cho Heroku (hoặc một dịch vụ cloud PaaS khác), hoặc đơn giản là muốn thử một thứ gì đó khác.</dd>
+</dl>
+
+<h2 id="Thêm_các_bài_hướng_dẫn">Thêm các bài hướng dẫn</h2>
+
+<div>
+<p>Các bài hướng dẫn kết thúc tại đó (đến hiện tại). Nếu bạn muốn mở rộng, các chủ đề thú vị khác để nói đến là:</p>
+
+<ul>
+ <li>Sử dụng phiên (sessions)</li>
+ <li>Xác thực người dùng</li>
+ <li>Định quyền người dùng và các quyền hạn</li>
+ <li>Kiểm thử một ứng dụng web Express</li>
+ <li>An ninh cho các ứng dụng web Express.</li>
+</ul>
+
+<p>Và đương nhiên sẽ rất tuyệt nếu có một bài tập đánh giá!</p>
+</div>
diff --git a/files/vi/learn/server-side/express_nodejs/mongoose/index.html b/files/vi/learn/server-side/express_nodejs/mongoose/index.html
new file mode 100644
index 0000000000..fdf6531d75
--- /dev/null
+++ b/files/vi/learn/server-side/express_nodejs/mongoose/index.html
@@ -0,0 +1,800 @@
+---
+title: 'Hướng dẫn Express Phần 3: Sử dụng Database (với Mongoose)'
+slug: Learn/Server-side/Express_Nodejs/mongoose
+translation_of: Learn/Server-side/Express_Nodejs/mongoose
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/skeleton_website", "Learn/Server-side/Express_Nodejs/routes", "Learn/Server-side/Express_Nodejs")}}</div>
+
+<p class="summary">Bài viết này giới thiệu tổng quan về cơ sở dữ liệu và cách dùng chúng với các ứng dụng Node/Express. Sau đó nó sẽ chỉ cho ta thấy cách sử dụng <a href="http://mongoosejs.com/">Mongoose</a> để tạo ra kết nối đến cơ sở dữ liệu cho trang web <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">LocalLibrary</a>. Nó giải thích cách mà schema và model của đối tượng được định nghĩa, các kiểu trường chính, và cách thức xác thực cơ bản. Nó còn trình bày một số cách chính để bạn có thể truy cập tới dữ liệu của model.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Bài viết trước:</th>
+ <td><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/skeleton_website">Express Tutorial Part 2: Creating a skeleton website</a></td>
+ </tr>
+ <tr>
+ <th scope="row">Mục tiêu:</th>
+ <td>Có thể thiết kế và tự tạo model của riêng mình thông qua Mongoose.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Khái_quát">Khái quát</h2>
+
+<p>Thủ thư sẽ dùng trang web Local Library để lưu trữ thông tin về sách và người mượn, trong khi các bạn đọc sẽ dùng nó để kiếm sách, tìm xem có bao nhiêu cuốn có sẵn, và tiếp tục như thế hoặc làm thủ tục mượn sách. Để có thể lưu trữ và truy xuất thông tin một cách hiệu quả, ta sẽ lưu trữ tất cả trong một <em>cơ sở dữ liệu</em>.</p>
+
+<p>Các ứng dụng Express có thể dùng nhiều loại cơ sở dữ liệu khác nhau, và có khá là nhiều hướng tiếp cận để bạn có thể thi hành <strong>C</strong>reate, <strong>R</strong>ead, <strong>U</strong>pdate and <strong>D</strong>elete (CRUD). Bài viết này sẽ cung cấp khái quát một số lựa chọn có thể áp dụng, và sẽ đi vào phân tích một phương pháp nhất định.</p>
+
+<h3 id="Tôi_có_thể_dùng_cơ_sở_dữ_liệu_nào">Tôi có thể dùng cơ sở dữ liệu nào?</h3>
+
+<p>Ứng dụng<em> Express</em> có thể dùng bất cứ cơ sở dữ liệu nào được hỗ trợ bởi <em>Node</em> (Chính <em>Express</em> không đưa ra bất cứ đặc tả chỉ tiết hành vi hay ràng buộc nào về hệ quản trị cơ sở dữ liệu). Thành ra có <a href="https://expressjs.com/en/guide/database-integration.html">rất nhiều thứ</a> để bạn thoả sức chọn lựa, bao gồm PostgreSQL, MySQL, Redis, SQLite, và MongoDB.</p>
+
+<p>Khi chọn một cơ sở dữ liệu, bạn nên cân nhắc những thứ như là độ khó, hiệu năng, dễ dàng bảo trì, chi phí, sự hỗ trợ của cộng đồng, vân vân và mây mây. Do chưa có cơ sở dữ liệu nào đạt được danh hiệu 'tốt nhất', nên ta có thể lựa chọn hầu như mọi giải pháp vừa kể trên cho một trang cỡ nhỏ tới vừa như trang Local Library của chúng ta.</p>
+
+<p>Để biết thêm chi tiết để tiện đường lựa chọn: <a href="https://expressjs.com/en/guide/database-integration.html">Database integration</a> (Tài liệu của Express).</p>
+
+<h3 id="Cách_nào_tốt_nhất_để_thao_tác_với_cơ_sở_dữ_liệu">Cách nào tốt nhất để thao tác với cơ sở dữ liệu?</h3>
+
+<p>Có hai hướng tiếp cận để tương tác với một cơ sở dữ liệu: </p>
+
+<ul>
+ <li>Sử dụng ngôn ngữ truy vấn của riêng cơ sở dữ liệu đó (ví dụ như SQL)</li>
+ <li>Sử dụng Object Data Model ("ODM") / Object Relational Model ("ORM"). ODM/ORM đại diện cho dữ liệu của trang web dưới dạng đối tượng trong JavaScript, sau đó ánh xạ tới cơ sở dữ liệu bên dưới. Một vài ORMs được gắn với một cơ sở dữ liệu nào đó, trong khi số khác chỉ là một cầu nối giữa cơ sở dữ liệu và phần code backend.</li>
+</ul>
+
+<p>Sử dụng ngôn ngữ truy vấn được hỗ trợ bởi cơ sở dữ liệu (như là SQL) sẽ đạt được <em>hiệu suất</em> cao nhất. ODM thường chậm hơn bởi nó phải thông dịch mã để có thể truy vấn giữa đối tượng và định dạng của cơ sở dữ liệu, mà không dùng được các truy vấn hiệu quả nhất của cơ sở dữ liệu (điều này càng nghiêm trọng hơn khi ORM được sử dụng cho nhiều dạng cơ sở dữ liệu khác nhau, và phải tạo ra nhiều điều khoản lằng nhằng hơn đối với lượng tính năng được cơ sở dữ liệu hỗ trợ).</p>
+
+<p>Điểm mạnh của ORM là lập trình viên có thể giữ tư duy như với đối tượng của JavaScript thay vì phải ngôn ngữ thuần tuý viết riêng cho cơ sở dữ liệu — điều này càng đúng khi bạn phải làm việc với nhiều loại cơ sở dữ liệu (trên cùng hoặc khác trang web). ORM còn cung cấp các tính năng để thực hiện xác thực và kiểm tra dữ liệu.</p>
+
+<div class="note">
+<p><strong>Mẹo:</strong>  Sử dụng ODM/ORMs thường giúp giảm thiểu chi phí phát triển và bảo trì! Trừ khi bạn đã quá thân thuộc với ngôn ngữ truy vấn thuần tuý hoặc hiệu suất là trên hết, bạn nên cân nhắc đến việc sử dụng ODM.</p>
+</div>
+
+<h3 id="Tôi_nên_dùng_ORMODM_nào">Tôi nên dùng ORM/ODM nào?</h3>
+
+<p>Có nhiều giải pháp cho ODM/ORM có sẵn trên trang quản lý gói NPM (tìm theo nhãn <a href="https://www.npmjs.com/browse/keyword/odm">odm</a> và <a href="https://www.npmjs.com/browse/keyword/orm">orm</a>!).</p>
+
+<p>Vào thời điểm viết bài này có một số giải pháp phổ biến như sau:</p>
+
+<ul>
+ <li><a href="https://www.npmjs.com/package/mongoose">Mongoose</a>: Mongoose là một công cụ mô hình hoá đối tượng <a href="https://www.mongodb.org/">MongoDB</a>, được thiết kế để làm việc trên môi trường bất đồng bộ.</li>
+ <li><a href="https://www.npmjs.com/package/waterline">Waterline</a>: Một ORM trích xuất từ <a href="http://sailsjs.com/">Sails</a> framework, có nền tảng là Express. Nó cung cấp một bộ API tiêu chuẩn để truy cập vào vô số kiểu cơ sở dữ liệu khác nhau, bao gồm Redis, mySQL, LDAP, MongoDB, và Postgres.</li>
+ <li><a href="https://www.npmjs.com/package/bookshelf">Bookshelf</a>: Trên nền promise và giao diện callback truyền thống, cung cấp hỗ trợ transaction, eager/nested-eager relation loading, sự kết hợp đa hình, and hỗ trợ quan hệ một-một, một-nhiều, nhiều-nhiều. Làm việc với PostgreSQL, MySQL, và SQLite3.</li>
+ <li><a href="https://www.npmjs.com/package/objection">Objection</a>: Vận dụng hết sức mạnh của SQL và hạ tầng cơ sở dữ liệu bên dưới (hỗ trợ SQLite3, Postgres, và MySQL) theo cách dễ dàng nhất có thể.</li>
+ <li>
+ <p><a href="https://www.npmjs.com/package/sequelize">Sequelize</a> là một ORM nền Promise dành cho Node.js và io.js. Nó hỗ trợ biên dịch PostgreSQL, MySQL, MariaDB, SQLite và MSSQL và hỗ trợ giao tác cứng, các quan hệ, read replication và nhiều hơn thế.</p>
+ </li>
+ <li>
+ <p><a href="https://node-orm.readthedocs.io/en/latest/">Node ORM2 </a>là Trình quản lý mối quan hệ đối tượng cho NodeJS. Nó hỗ trợ MySQL, SQLite và Progress, giúp làm việc với cơ sở dữ liệu bằng cách sử dụng phương pháp hướng đối tượng.</p>
+ </li>
+ <li>
+ <p><a href="http://1602.github.io/jugglingdb/">JugglingDB </a>là ORM DB chéo cho NodeJS, cung cấp giao diện chung để truy cập hầu hết các định dạng cơ sở dữ liệu phổ biến. Hiện đang hỗ trợ MySQL, SQLite3, Postgres, MongoDB, Redis và js-memory-Storage (công cụ tự viết để chỉ sử dụng thử nghiệm).</p>
+ </li>
+</ul>
+
+<p>Như một luật ngầm định, bạn nên cân nhắc cả tính năng được công bố cũng như "hoạt động cộng đồng" (tải xuống, sự đóng góp, báo lỗi, chất lượng của tài liệu, vân vân và mây mây) khi lựa chọn một giải pháp. Vào thời điểm viết bài thì Mongoose là một ORM phổ biến nhất, và là lựa chọn hợp lý nếu bạn dùng MongoDB làm cơ sở dữ liệu của mình.</p>
+
+<h3 id="Sử_dụng_Mongoose_và_MongoDb_cho_LocalLibrary">Sử dụng Mongoose và MongoDb cho LocalLibrary</h3>
+
+<p>Đối với ví dụ <em>Local Library</em> (và cho cả phần còn lại của bài viết này) ta sẽ sử dụng <a href="https://www.npmjs.com/package/mongoose">Mongoose ODM</a> để truy cập dữ liệu thư viện của chúng ta. Mongoose hoạt động như một frontend của <a href="https://www.mongodb.com/what-is-mongodb">MongoDB</a>, cơ sở dữ liệu mở dạng <a href="https://en.wikipedia.org/wiki/NoSQL">NoSQL</a> sử dụng mô hình dữ liệu hướng document. Một “collection” và “documents”, trong cơ sở dữ liệu MongoDB, <a href="https://docs.mongodb.com/manual/core/databases-and-collections/#collections">tương tự với</a> một “table” và “row” trong cơ sở dữ liệu quan hệ.</p>
+
+<p>ODM và kết hợp cơ sở dữ liệu này cực kì phổ biến trong cộng đồng Node, phần lớn là bởi kho chứa document và hệ thống truy vấn khá là giống với JSON, vã dĩ nhiên rất đỗi thân quen với các lập trình viên JavaScript.</p>
+
+<div class="note">
+<p><strong>Mẹo:</strong> Bạn không cần phải biết gì về MongoDB để có thể sử dụng được Mongoose, mặc dù vài phần trong <a href="http://mongoosejs.com/docs/guide.html">tài liệu của Mongoose</a> <em>sẽ</em> dễ đọc hiểu hơn nếu bạn đã quen với MongoDB rồi.</p>
+</div>
+
+<p>Phần còn lại của bài viết này hướng dẫn cách để định nghĩa và truy cập schema và model của Mongoose thông qua ví dụ làm trang web cho <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">LocalLibrary</a>.</p>
+
+<h2 id="Thiết_kế_model_LocalLibrary">Thiết kế model LocalLibrary</h2>
+
+<p>Trước khi nhảy bổ vào viết code cho model, sẽ tốt hơn nếu ta dành vài phút để nghĩ về dữ liệu ta cần phải lưu trữ và mối quan hệ giữa các đối tượng khác nhau.</p>
+
+<p>Chúng ta biết rằng chúng ta cần phải lữu trữ dữ liệu về sách (tựa đề, tóm tắt, tác giả, thể loại, mã số tiêu chuẩn quốc tế cho sách) và sẽ có khá nhiều cuốn giống nhau (với mã số quốc tế riêng biệt, tình trạng, vân vân.). Có lẽ ta sẽ cần lưu trữ nhiều thông tin về tác giả hơn chỉ là tên của người đó, và có vô số tác giả trùng hoặc có tên na ná nhau. Chúng ta muốn phân loại thông tin dựa theo tựa đề, tác giả, thể loại, và kiểu sách.</p>
+
+<p>Công cuộc thiết kế model yêu cầu thiết kế các mô hình riêng rẽ cho từng "object" (nhóm các thông tin có liên quan với nhau). Trong trường hợp này thì các object ấy hẳn là sách, các thuộc tính của sách, và tác giả.</p>
+
+<p>Bạn chắc hẳn sẽ muốn biểu diễn mô hình dưới dạng danh sách liệt kê (ví dụ như một danh sách các lựa chọn), thay vì code cứng tất tần tật — việc này được đề nghị khi các lựa chọn vẫn chưa được liệt kê hết hoặc có thể bị thay đổi. Ứng viên sáng giá cho việc mô hình hoá này chính là thể loại sách (ví dụ như Khoa học Viễn tưởng, Ngôn tình, hoặc gì đó tương tự.)</p>
+
+<p>Khi đã quyết định được các mô hình và trường dữ liệu, ta cần phải suy ngẫm về mối quan hệ giữa chúng.</p>
+
+<p>Để làm tốt việc này, ta sẽ dùng biểu đồ liên hệ UML như bên dưới để biểu diễn các model ta sắp định nghĩa ra (trong các hộp). Như đã nói ở trên, ta vừa tạo ra model cho sách (chi tiết cơ bản nhất cho sách), phần tử của sách (lượng bản sách còn trong hệ thống), và tác giả. Chúng ta cũng vừa quyết định sẽ tạo thêm model cho thể loại, để giá trị của nó thay đổi động. Ta cũng vừa quyết định sẽ không tạo mô hình cho <code>BookInstance:status</code> — chúng ta sẽ code cứng phần này đến một giá trị có thể chấp nhận được bởi ta không mong muốn giá trị của nó bị thay đổi. Bạn có thể thấy trong mỗi hộp là tên của mô hình, tên của các trường và kiểu dữ liệu tương ứng, đồng thời cả các thuộc tính và kiểu trả về nữa.</p>
+
+<p>Biểu đồ còn chỉ ra mối quan hệ giữa các mô hình, bao gồm cả <em>bội số</em>. Bội số là các con số nhỏ nhỏ nằm trên các đường thẳng nối các hộp lại với nhau (lớn nhất và nhỏ nhất) để chỉ ra độ liên hệ trong các mối quan hệ giữa các mô hình với nhau. Láy ví dụ như trong hình dưới, những đoạn kẻ nối giữa các hộp biểu diễn rằng <code>Book</code> và <code>Genre</code> liên quan đến nhau. Con số nằm gần với mô hình <code>Book</code> chỉ ra rằng Book phải có từ 0 đến nhiều <code>Genre</code> (bao nhiêu tuỳ thích), trong khi con số nằm ở đầu đoạn bên kia của <code>Genre</code> lại chỉ ra rằng nó có 0 hoặc nhiều liên hệ với Book.</p>
+
+<div class="note">
+<p><strong>Lưu ý</strong>: Như đã nói trong <a href="#related_documents">Mongoose primer</a> phía dưới, thường sẽ tốt hơn nếu có một trường riêng để định nghĩa mối quan hệ giữa documents/models chỉ trong <em>một</em> mô hình (bạn vẫn có thể tìm thấy mối quan hệ ngược lại bằng cách tìm kiếm <code>_id</code> liên quan trong các mô hình khác). Bên dưới biểu diễn mối quan hệ giữa Book/Genre and Book/Author trong Book schema, và mối quan hệ giữa Book/BookInstance trong BookInstance Schema. Việc lựa chọn này hơi cảm tính — ta hoàn toàn có thể định nghĩa các trường trong một schema khác.</p>
+</div>
+
+<p><img alt="Mongoose Library Model with correct cardinality" src="https://mdn.mozillademos.org/files/15645/Library%20Website%20-%20Mongoose_Express.png" style="height: 620px; width: 737px;"></p>
+
+<div class="note">
+<p><strong>Lưu ý</strong>: Phần tiếp theo cung cấp kiến thức cơ bản giải thích cách mô hình được định nghĩa và sử dụng. Ta sẽ tìm cách để xây dựng đống mô hình vừa vẽ ra trong biểu đồ trên.</p>
+</div>
+
+<h2 id="Mongoose_primer">Mongoose primer</h2>
+
+<p>Phần này giới thiệu khái quát cách để kết nối Mongoose với một cơ sở dữ liệu MongoDB, cách định nghĩa một schema và một model, và cách viết vài câu truy vấn đơn giản. </p>
+
+<div class="note">
+<p><strong>Lưu ý:</strong> Cái primer này "bị ảnh hưởng mạnh" bởi <a href="https://www.npmjs.com/package/mongoose">Mongoose quick start</a> trên <em>npm</em> và <a href="http://mongoosejs.com/docs/guide.html">official documentation</a>.</p>
+</div>
+
+<h3 id="Cài_đặt_Mongoose_và_MongoDB">Cài đặt Mongoose và MongoDB</h3>
+
+<p>Mongoose được cài đặt vào trong project của bạn (<strong>package.json</strong>) giống hệt như các dependency khác — dùng NPM. Để cài đặt nó, chạy câu lệnh sau trong thư mục project của bạn:</p>
+
+<pre class="brush: bash"><code>npm install mongoose</code>
+</pre>
+
+<p>Sau khi cài xong, <em>Mongoose</em> sẽ tự động thêm mọi dependencies của nó, bao gồm cả driver cơ sở dữ liệu cho MongoDB, nhưng nó sẽ không cài đặt MongoDB đâu nhé. Nếu bạn muốn cài đặt một máy chủ MongoDB thì bạn có thể <a href="https://www.mongodb.com/download-center">tải xuống bộ cài tại đây</a>, dành cho nhiều vô số hệ điều hành khác nhau và cài đặt nó trên hệ thống của mình. Bạn cũng có thể sử dụng MongoDB trên đám mây.</p>
+
+<div class="note">
+<p><strong>Lưu ý:</strong> Trong bài viết này, ta sẽ sử dụng mLab, một <em>cơ sở dữ liệu được cung cấp dưới dạng dịch vụ</em> trên nền tảng điện toán đám mây và chọn <a href="https://mlab.com/plans/pricing/">sandbox tier</a> nhé. Cái này khá hợp với khâu phát triển, và không phụ thuộc vào việc "cài đặt" hệ điều hành (cơ-sở-dữ-liệu-cung-cấp-dưới-dạng-dịch-vụ là một hướng tiếp cận nếu sử dụng trong dự án thật).</p>
+</div>
+
+<h3 id="Kết_nối_với_MongoDB">Kết nối với MongoDB</h3>
+
+<p><em>Mongoose</em> yêu cầu một kết nối tới cơ sở dữ liệu MongoDB. Bạn có thể <code>require()</code> và kết nối cục bộ tới cơ sở dữ liệu thông qua <code>mongoose.connect()</code>, như bên dưới.</p>
+
+<pre class="brush: js">//Nhập mô-đun mongoose
+var mongoose = require('mongoose');
+
+//Thiết lập một kết nối mongoose mặc định
+var mongoDB = 'mongodb://127.0.0.1/my_database';
+mongoose.connect(mongoDB);
+//Ép Mongoose sử dụng thư viện promise toàn cục
+mongoose.Promise = global.Promise;
+//Lấy kết nối mặc định
+var db = mongoose.connection;
+
+//Ràng buộc kết nối với sự kiện lỗi (để lấy ra thông báo khi có lỗi)
+db.on('error', console.error.bind(console, 'MongoDB connection error:'));</pre>
+
+<p>Bạn có thể lấy ra đối tượng mặc định <code>Connection</code> với <code>mongoose.connection</code>. Ngay khi đã kết nối, sự kiện sẽ nổ ra trên thuộc tính <code>Connection</code>.</p>
+
+<div class="note">
+<p><strong>Mẹo:</strong> Nếu bạn muốn thêm mới các kết nối khác thì có thể dùng <code>mongoose.createConnection()</code>. Vẫn dùng chung định dạng URI (bao gồm máy chủ, cơ sở dữ liệu, cổng, lựa chọn khác.) như <code>connect()</code> và trả về một đối tượng <code>Connection</code>).</p>
+</div>
+
+<h3 id="Định_nghĩa_và_tạo_ra_các_model">Định nghĩa và tạo ra các model</h3>
+
+<p>Model được <em>định nghĩa </em>thông qua giao diện <code>Schema</code>. Schema định nghĩa các trường được lưu trong mỗi document đi kèm với điều kiện xác thực và giá trị mặc định cho chúng. Hơn nữa, bạn có thể khởi tạo các thuộc tính tĩnh và phương thức hỗ trợ để làm việc với kiểu dữ liệu của bạn dễ dàng hơn, và cả các đặc tính ảo để có thể dùng như bất cứ trường nào, mà không bị lưu vào trong cơ sở dữ liệu (ta sẽ bàn về vấn đề này sau).</p>
+
+<p>Schema sau đó được "biên dịch" thành mô hình qua phương thức <code>mongoose.model()</code>. Một khi đã có mô hình thì bạn có thể dùng nó để tìm, thêm, sửa, và xoá các đối tượng cùng kiểu.</p>
+
+<div class="note">
+<p><strong>Lưu ý:</strong> Mỗi mô hình có liên kết tới một <em>bộ sưu tập</em> các<em> tài liệu</em> trong cơ sở dữ liệu MongoDB. Documents sẽ chứa các trường/kiểu schema được định nghĩa trong mô hình <code>Schema</code>.</p>
+</div>
+
+<h4 id="Định_nghĩa_schema">Định nghĩa schema</h4>
+
+<p>Đoạn code bên dưới trình bày cách cách thức tạo ra một Schema đơn giản. Đầu tiên bạn <code>require()</code> mongoose, rồi dùng phương thức khởi tạo của Schema để tạo ra một biến schema, định nghĩa một vài trường trong tham số truyền vào của phương thức khởi tạo.</p>
+
+<pre class="brush: js">//Require Mongoose
+var mongoose = require('mongoose');
+
+//Định nghĩa một schema
+var Schema = mongoose.Schema;
+
+var SomeModelSchema = new Schema({
+ a_string: String,
+ a_date: Date
+});
+</pre>
+
+<p>Trong trường hợp trên ta chỉ có 2 trường, một string và một date. Trong phần tiếp theo, ta sẽ thêm một vài trường khác, xác thực, và một số phương thức khác.</p>
+
+<h4 id="Thêm_mới_một_mô_hình">Thêm mới một mô hình</h4>
+
+<p>Mô hình được tạo ra từ schema qua phương thức <code>mongoose.model()</code>:</p>
+
+<pre class="brush: js">// Định nghĩa schema
+var Schema = mongoose.Schema;
+
+var SomeModelSchema = new Schema({
+ a_string: String,
+  a_date: Date
+});
+
+<strong>// Biên dịch mô hình từ schema
+var SomeModel = mongoose.model('SomeModel', SomeModelSchema );</strong></pre>
+
+<p>Tham số thứ nhất là tên riêng cho collection sắp được tạo ra cho mô hình của bạn (Mongoose sẽ khởi tạo một collection cho model <em>SomeModel</em> ở phía trên), và tham số thứ hai là schema mà bạn muốn dùng để tạo ra mô hình.</p>
+
+<div class="note">
+<p><strong>Lưu ý:</strong> Khi đã có các model class, bạn có thể sử dụng chúng để thêm, sửa, hoặc xoá các bản ghi, và để chạy các câu truy vấn lấy tất cả các bản ghi hoặc tạo các tập hợp con cho một số lượng bản ghi nhất định. Ta sẽ tìm hiểu việc này trong phần <a href="#">Sử dụng mô hình</a>, và khi ta tạo khung nhìn.</p>
+</div>
+
+<h4 id="Kiểu_Schema_(các_trường)">Kiểu Schema (các trường)</h4>
+
+<p>Một schema có thể có số trường thông tin tuỳ ý — mỗi trường đại diện cho một document lưu trong <em>MongoDB</em>. Schema trong ví dụ bên dưới trình bày các kiểu đơn giản của các trường cũng như cách định nghĩa chúng.</p>
+
+<pre class="brush: js">var schema = new Schema(
+{
+ name: <strong>String</strong>,
+ binary: <strong>Buffer</strong>,
+ living: <strong>Boolean</strong>,
+ updated: { type: <strong>Date</strong>, default: Date.now },
+ age: { type: <strong>Number</strong>, min: 18, max: 65, required: true },
+ mixed: <strong>Schema.Types.Mixed</strong>,
+ _someId: <strong>Schema.Types.ObjectId</strong>,
+ array: <strong>[]</strong>,
+ ofString: [<strong>String</strong>], // Bạn có thể tạo mảng cho các trường khác
+ nested: { stuff: { type: <strong>String</strong>, lowercase: true, trim: true } }
+})</pre>
+
+<p>Hầu hết các <a href="http://mongoosejs.com/docs/schematypes.html">SchemaTypes</a> (đống miêu tả sau từ “type:” hoặc sau tên trường) đều tự định nghĩa chính nó. Ngoại trừ:</p>
+
+<ul>
+ <li><code>ObjectId</code>: Đại diện cho các thuộc tính đặc trưng của mô hình trong cơ sở dữ liệu. Chẳng hạn, một cuốn sách có thể dùng thứ này để đại diện cho tác giả của nó. Nó còn sẽ chứa cả ID đặc trưng (<code>_id</code>) cho đối tượng đặc trưng. Ta có thể dùng phương thức <code>populate()</code> để lấy các thông tin liên quan nếu cần thiết.</li>
+ <li><a href="http://mongoosejs.com/docs/schematypes.html#mixed">Mixed</a>: Một kiểu schema chồng chập.</li>
+ <li><font face="Consolas, Liberation Mono, Courier, monospace">[]</font>: Mảng. Bạn có thể sử dụng các phương thức cho mảng riêng của JavaScript trên các mô hình này (push, pop, unshift, shift, reduce, vân vân và mây mây.). Ví dụ phía trên có một mảng đối tượng không định kiểu và một mảng đối tượng kiểu <code>String</code>, bạn vẫn có thể định nghĩa một mảng tuỳ ý kiểu đối tượng.</li>
+</ul>
+
+<p>Đoạn code cũng chỉ ra hai cách để khai báo một trường:</p>
+
+<ul>
+ <li><em>Tên</em> và <em>kiểu</em> của trường là một cặp khoá-giá trị (ví dụ như với các trường <code>name</code>, <code>binary</code> và <code>living</code>).</li>
+ <li><em>Tên</em> trường chứa một đối tượng gồm có <code>type</code>, và nhiều <em>lựa chọn</em> khác. Lựa chọn bao gồm những thứ như là:
+ <ul>
+ <li>giá trị mặc định.</li>
+ <li>công cụ xác thực định sẵn (như giá trị max/min) và các hàm tuỳ chỉnh.</li>
+ <li>Trường ấy có bắt buộc (required) hay không</li>
+ <li>Trường kiểu <code>String</code> nên tự động ở kiểu chữ nhỏ, chữ to, hoặc tỉa gọn (ví dụ <code>{ type: <strong>String</strong>, lowercase: true, trim: true }</code>)</li>
+ </ul>
+ </li>
+</ul>
+
+<p>Để biết thêm chi tiết, mời bạn xem thêm <a href="http://mongoosejs.com/docs/schematypes.html">SchemaTypes</a> (Tài liệu của Mongoose).</p>
+
+<h4 id="Xác_thực">Xác thực</h4>
+
+<p>Mongoose cung cấp một số hàm xác thực định sẵn và tuỳ chỉnh, và các hàm xác thực đồng bộ cũng như bất đồng bộ. Nó cho phép bạn đặc tả cả phạm vi chấp nhận hoặc giá trị và thông báo lỗi khi hàm xác thực gặp phải sự cố trong mọi trường hợp.</p>
+
+<p>Các hàm xác thực định sẵn bao gồm:</p>
+
+<ul>
+ <li>Tất cả các <a href="http://mongoosejs.com/docs/schematypes.html">SchemaTypes</a> đều có hàm xác thực là <a href="http://mongoosejs.com/docs/api.html#schematype_SchemaType-required">required</a>. Hàm này xác minh rằng liệu trường dữ liệu đó có bắt buộc phải được cung cấp nếu muốn lưu lại vào trong document hay không.</li>
+ <li><a href="http://mongoosejs.com/docs/api.html#schema-number-js">Numbers</a> có hai hàm là <a href="http://mongoosejs.com/docs/api.html#schema_number_SchemaNumber-min">min</a> và <a href="http://mongoosejs.com/docs/api.html#schema_number_SchemaNumber-max">max</a>.</li>
+ <li><a href="http://mongoosejs.com/docs/api.html#schema-string-js">Strings</a> có:
+ <ul>
+ <li><a href="http://mongoosejs.com/docs/api.html#schema_string_SchemaString-enum">enum</a>: đặc tả tập các giá trị được cho phép truyền vào trường tương ứng.</li>
+ <li><a href="http://mongoosejs.com/docs/api.html#schema_string_SchemaString-match">match</a>: đặc tả một regex để tạo luật cho xâu truyền vào.</li>
+ <li><a href="http://mongoosejs.com/docs/api.html#schema_string_SchemaString-maxlength">maxlength</a> và <a href="http://mongoosejs.com/docs/api.html#schema_string_SchemaString-minlength">minlength</a> cho xâu truyền vào.</li>
+ </ul>
+ </li>
+</ul>
+
+<p>Ví dụ bên dưới (hơi khác một chút so với tài liệu của Mongoose) chỉ ra cách để thêm các hàm xác minh và thông báo lỗi:</p>
+
+<pre class="brush: js"><code>
+ var breakfastSchema = new Schema({
+ eggs: {
+ type: Number,
+ min: [6, 'Too few eggs'],
+ max: 12
+ required: [true, 'Why no eggs?']
+ },
+ drink: {
+ type: String,
+ enum: ['Coffee', 'Tea', 'Water',]
+ }
+ });
+</code></pre>
+
+<p>Để biết thêm thông tin chi tiết về các hàm xác minh, hãy vào <a href="http://mongoosejs.com/docs/validation.html">Validation</a> (tài liệu của Mongoose) để tìm đọc.</p>
+
+<h4 id="Thuộc_tính_ảo">Thuộc tính ảo</h4>
+
+<p>Thuộc tính ảo là các thuộc tính của document mà bạn có thể lấy ra và đặt lại mà không làm ảnh hưởng tới MongoDB. Hàm lấy ra hiệu quả cho việc định dạng lại hoặc kết hợp các trường, trong khi hàm đặt lại lại hữu dụng cho việc phân tách một giá trị riêng lẻ thành nhiều giá trị trong cơ sở dữ liệu. Ví dụ trong tài liệu khởi tạo (và huỷ tạo) một thuộc tính ảo tên đầy đủ từ trường họ và tên, điều đó sẽ dễ dàng và sạch sẽ hơn thay vì tạo ra một trường họ tên mỗi khi có ai đó sử dụng mẫu.</p>
+
+<div class="note">
+<p><strong>Lưu ý:</strong> Ta sẽ dùng thuộc tính ảo trong thư viện để định nghĩa một URL đặc trưng cho từng bản ghi của mô hình thông qua một đường dẫn và giá trị của mỗi bản ghi <code>_id</code> của mỗi bản ghi.</p>
+</div>
+
+<p>Để biết thêm chi tiết hãy vào <a href="http://mongoosejs.com/docs/guide.html#virtuals">Virtuals</a> (tài liệu của Mongoose).</p>
+
+<h4 id="Phương_thức_và_câu_truy_vấn_trợ_giúp">Phương thức và câu truy vấn trợ giúp</h4>
+
+<p>Một schema có thể còn có <a href="http://mongoosejs.com/docs/guide.html#methods">phương thức biến</a>, <a href="http://mongoosejs.com/docs/guide.html#statics">phương thức tĩnh</a>, và <a href="http://mongoosejs.com/docs/guide.html#query-helpers">hỗ trợ truy vấn</a>. Phương thức biến và phương thức tĩnh gần như tương tự nhau, điểm khác biệt duy nhất là phương thức tĩnh liên kết với một bản ghi xác định và có quyền truy cập tới đối tượng hiện tại. Hỗ trợ truy vấn cho phép bạn mở rộng <a href="http://mongoosejs.com/docs/queries.html">chainable query builder API</a> của mongoose (ví dụ như, cho phép bạn thêm câu truy vấn "byName" sau các phương thức <code>find()</code>, <code>findOne()</code> và <code>findById()</code>).</p>
+
+<h3 id="Sử_dụng_mô_hình">Sử dụng mô hình</h3>
+
+<p>Ngay khi đã có một schema, bạn có thể dùng nó để tạo ra các mô hình. Mô hình đại diện cho một bộ sưu tập các tài liệu trong cơ sở dữ liệu mà bạn có thể tìm kiếm, trong khi các phần tử của mô hình đại diện cho từng tài liệu mà bạn có thể lưu trữ và truy xuất.</p>
+
+<p>Chúng ta chỉ có thể tìm hiểu sơ qua như trên thôi. Nếu muốn chi tiết hơn thì hãy vào xem: <a href="http://mongoosejs.com/docs/models.html">Models</a> (tài liệu của Mongoose).</p>
+
+<h4 id="Thêm_mới_và_chỉnh_sửa_tài_liệu">Thêm mới và chỉnh sửa tài liệu</h4>
+
+<p>Để thêm mới một bản ghi, bạn có thể định nghĩa một phần tử của mô hình và sau đó dùng lời gọi <code>save()</code>. Ví dụ bên dưới chỉ ra rằng SomeModel là một đối tượng (chỉ có một trường là "name") mà ta vừa tạo ra từ schema của mình.</p>
+
+<pre class="brush: js"><code>// Thêm mới một phần tử của mô hình SomeModel
+var awesome_instance = new </code>SomeModel<code>({ name: 'awesome' });
+
+// Lưu phần tử vừa thêm mới lại, thông qua việc truyền vào một hàm callback
+awesome_instance.save(function (err) {
+ if (err) return handleError(err);
+ // saved!
+});
+</code></pre>
+
+<p>Việc thêm bản ghi (đi kèm với sửa, xoá, và tìm kiếm) là các công việc bất đồng bộ — bạn phải truyền vào một hàm callback sau khi công việc hoàn tất. API sử dụng quy ước lỗi-trước, thế nên tham số thứ nhất trong hàm callback luôn là một giá trị lỗi (hoặc null). Nếu API trả về kết quả nào đó, nó sẽ được truyền vào qua tham số thứ hai.</p>
+
+<p>Bạn cũng có thể sử dụng <code>create()</code> để vừa định nghĩa một phần tử của mô hình vừa lưu lại nó luôn. Hàm callback sẽ trả về một lỗi ứng với tham số thứ nhất và phần tử của mô hình vừa khởi tạo qua tham số thứ hai.</p>
+
+<pre class="brush: js">SomeModel<code>.create({ name: 'also_awesome' }, function (err, awesome_instance) {
+ if (err) return handleError(err);
+ // lưu!
+});</code></pre>
+
+<p>Mỗi mô hình đều có một kết nối liên quan  (kết nối sẽ mặc định nếu dùng lệnh <code>mongoose.model()</code>). Bạn thêm mới một kết nối và gọi lệnh <code>.model()</code> để tạo thêm tài liệu trên một cơ sở dữ liệu khác.</p>
+
+<p>Bạn có thể truy cập vào trường của bản ghi mới thông qua cú pháp chấm (.) , và thay đổi giá trị ở trong. Bạn sẽ phải gọi <code>save()</code> hoặc <code>update()</code> để lưu lại giá trị vừa chỉnh sửa vào cơ sở dữ liệu.</p>
+
+<pre class="brush: js">// Truy cập vào trường dữ liệu của bản ghi qua cú pháp (.)
+console.log(<code>awesome_instance.name</code>); //sẽ in ra '<code>also_awesome</code>'
+
+// Thay đổi bản ghi bằng cách chỉnh sửa trường thông tin, sau đó gọi lệnh save().
+<code>awesome_instance</code>.name="New cool name";
+<code>awesome_instance.save(function (err) {
+  if (err) return handleError(err); // lưu!
+  });</code>
+</pre>
+
+<h4 id="Tìm_kiếm_các_bản_ghi">Tìm kiếm các bản ghi</h4>
+
+<p>Bạn có thể tìm kiếm các bản ghi bằng các phương thức truy vấn, viết các câu truy vấn như đối với một tài liệu JSON. Đoạn code phía dưới trình bày cách tìm kiếm các vận động viên chơi ten-nít trong cơ sở dữ liệu, chỉ trả về các trường như <em>tên</em> và <em>tuổi </em>của vận động viên. GIờ ta sẽ chỉ xác định ra một trường (thể thao) bạn có thể thêm bao nhiêu tiêu chí tuỳ ý, xác định thêm các tiêu chí với regex, hoặc loại bỏ tất cả các điều kiện để trả về tất cả các vận động viên.</p>
+
+<pre class="brush: js"><code>var Athlete = mongoose.model('Athlete', yourSchema);
+
+// tìm tất cả các vận động viên chơi tennis, chọn hai trường 'name' và 'age'
+Athlete.find({ 'sport': 'Tennis' }, 'name age', function (err, athletes) {
+ if (err) return handleError(err);
+ // 'athletes' chứa danh sách các vận động viên phù hợp với tiêu chí đã đề ra.
+})</code></pre>
+
+<p>Nếu bạn ném vào môt hàm callback, như ở trên, câu truy vấn sẽ được thực thi ngay lập tức. Hàm callback sẽ được gọi khi câu truy vấn hoàn tất.</p>
+
+<div class="note">
+<p><strong>Lưu ý:</strong> Tất cả các hàm callback trong Mongoose sử dụng mẫu <code>callback(error, result)</code>. Nếu có lỗi xảy ra khi thực hiện câu truy vấn, tham số <code>error</code> sẽ chứa tất cả các lỗi, và <code>result</code> sẽ trở thành null. Nếu câu truy vấn hợp lệ, tham số <code>error</code> sẽ trở thành null, và <code>result</code> sẽ chứa đựng kết quả của câu truy vấn.</p>
+</div>
+
+<p>Nếu bạn không truyền vào một hàm callback nào thì API sẽ trả về một giá trị kiểu <a href="http://mongoosejs.com/docs/api.html#query-js">Query</a>. Bạn có thể sử dụng đối tượng query này để kéo dài câu truy vấn trước khi thực thi nó (thông qua việc truyền vào một hàm callback) sau sử dụng phương thức <code>exec()</code>.</p>
+
+<pre class="brush: js"><code>// tìm kiếm tất cả các vận động viên
+var query = Athlete.find({ 'sport': 'Tennis' });
+
+// chọn ra hai trường 'name' và 'age'
+query.select('name age');
+
+// giới hạn kết quả lại 5 bản ghi
+query.limit(5);
+
+// sắp xếp theo tên
+query.sort({ age: -1 });
+
+// thực thi câu truy vấn
+query.exec(function (err, athletes) {
+ if (err) return handleError(err);
+ // athletes chứa một danh sách 5 vận động viên chơi tennis được xếp theo tên
+})</code></pre>
+
+<p>Ở trên ta đưa tất cả điều kiện truy vấn vào trong phương thức <code>find()</code>. Thay vì vậy ta cũng có thể sử dụng hàm <code>where()</code>, và ta có thể xâu chuỗi các lời gọi bằng cú pháp chấm (.) thay vì phải gọi từng câu riêng rẽ. Đoạn code phía dưới làm y chang phần trên, thêm vài điều kiện cho trường tuổi.</p>
+
+<pre><code>Athlete.
+ find().
+ where('sport').equals('Tennis').
+ where('age').gt(17).lt(50). //Điều kiện thêm vào sau hàm where
+ limit(5).
+ sort({ age: -1 }).
+ select('name age').
+ exec(callback); // callback ở đây là tên hàm callback của ta.</code></pre>
+
+<p>Phương thức <a href="http://mongoosejs.com/docs/api.html#query_Query-find">find()</a> lấy ra tất cả các bản ghi thoả mãn điều kiện, nhưng thường thì bạn chỉ muốn lấy ra một thôi. Các phương thức truy vấn phía dưới chỉ lấy ra một bản ghi:</p>
+
+<ul>
+ <li><code><a href="http://mongoosejs.com/docs/api.html#model_Model.findById">findById()</a></code>: Tìm kiếm tài liệu theo <code>id</code> (mỗi tài liệu có một <code>id</code> duy nhất).</li>
+ <li><code><a href="http://mongoosejs.com/docs/api.html#query_Query-findOne">findOne()</a></code>: Tìm kiếm một tài liệu dựa theo tiêu chí đặt vào.</li>
+ <li><code><a href="http://mongoosejs.com/docs/api.html#model_Model.findByIdAndRemove">findByIdAndRemove()</a></code>, <code><a href="http://mongoosejs.com/docs/api.html#model_Model.findByIdAndUpdate">findByIdAndUpdate()</a></code>, <code><a href="http://mongoosejs.com/docs/api.html#query_Query-findOneAndRemove">findOneAndRemove()</a></code>, <code><a href="http://mongoosejs.com/docs/api.html#query_Query-findOneAndUpdate">findOneAndUpdate()</a></code>: Tìm kiếm một tài liệu theo <code>id</code> hoặc theo tiêu chí và sửa hoặc xoá nó. Đây là các mẫu có ích khi cần phải tìm kiếm và chỉnh sửa.</li>
+</ul>
+
+<div class="note">
+<p><strong>Lưu ý:</strong> Còn có phương thức <code><a href="http://mongoosejs.com/docs/api.html#model_Model.count">count()</a></code> để đếm số lượng bản ghi phù hợp với điều kiện đề ra. Cái này sẽ có ích nếu bạn chỉ cần tìm ra số lượng thay vì phải kéo về tất cả các bản ghi.</p>
+</div>
+
+<p>Còn có nhiều thứ nữa mà bạn có thể làm với các câu truy vấn. Để biết thêm thông tin mời xem: <a href="http://mongoosejs.com/docs/queries.html">Queries</a> (tài liệu Mongoose).</p>
+
+<h4 id="Làm_việc_với_tài_liệu_liên_quan_—_sự_cư_ngụ">Làm việc với tài liệu liên quan — sự cư ngụ</h4>
+
+<p>Bạn có thể thêm mới mối liên quan giữa các tài liệu/phần tử của mô hình qua trường schema <code>ObjectId</code>, hoặc từ một tài liệu đến nhiều qua một mảng <code>ObjectIds</code>. Trường này lưu trữ id của mô hình liên quan. Nếu bạn muốn lấy nội dung của tài liệu liên quan, bạn có thể sử dụng phương thức <code><a href="http://mongoosejs.com/docs/api.html#query_Query-populate">populate()</a></code> trong câu truy vấn để thay thế id với đống dữ liệu tương ứng.</p>
+
+<p>Chẳng hạn, schema sau đây định nghĩa tác giả và tác phẩm. Mỗi tác giả có thể có nhiều tác phẩm, nên ta sử dụng một mảng đối tượng <code>ObjectId</code>. Mỗi tác phẩm có thể có một tác giả. Thuộc tính "ref" (được in đậm) kể cho ta biết schema nào mà model có thể gắn vào được.</p>
+
+<pre class="brush: js"><code>var mongoose = require('mongoose')
+ , Schema = mongoose.Schema
+
+var authorSchema = Schema({
+ name : String,
+ stories : [{ type: Schema.Types.ObjectId, <strong>ref</strong>: 'Story' }]
+});
+
+var storySchema = Schema({
+ author : { type: Schema.Types.ObjectId, <strong>ref</strong>: 'Author' },
+ title : String
+});
+
+var Story = mongoose.model('Story', storySchema);
+var Author = mongoose.model('Author', authorSchema);</code></pre>
+
+<p>Ta có thể lưu lại đống liên quan đến tài liệu tương ứng bằng cách gán cho nó giá trị <code>_id</code>. Đoạn bên dưới ta tạo ra một tác giả, rồi một cuốn sách và gắn id của tác giả vào trường tác giả của tác phẩm.</p>
+
+<pre class="brush: js"><code>var bob = new Author({ name: 'Bob Smith' });
+
+bob.save(function (err) {
+ if (err) return handleError(err);
+
+ //Bob giờ đã tồn tại, đến lúc tạo tác phẩm rồi
+ var story = new Story({
+ title: "Bob goes sledding",
+ author: bob._id // gắn _id của tác giả Bob. ID này được tạo ra mặc định!
+ });
+
+ story.save(function (err) {
+ if (err) return handleError(err);
+ // Bob giờ đã có tác phẩm của mình
+ });
+});</code></pre>
+
+<p>Tài liệu tác phẩm của ta giờ được nối với trường tác giả thông qua ID của trong tài liệu tác giả. Để lấy thông tin của tác giả ta dùng hàm <code>populate()</code>, như bên dưới.</p>
+
+<pre class="brush: js"><code>Story
+.findOne({ title: 'Bob goes sledding' })
+.populate('author') //Thay thế ID của tác giả bằng thông tin của tác giả!
+.exec(function (err, story) {
+ if (err) return handleError(err);
+ console.log('The author is %s', story.author.name);
+ // in ra "The author is Bob Smith"
+});</code></pre>
+
+<div class="note">
+<p><strong>Lưu ý:</strong> Ta vừa thêm tác giả vào tác phẩm, nhưng lại không hề thêm tác phẩm vào mảng <code>stories</code> của tác giả. Thế thì làm thế nào để lấy ra tất cả tác phẩm của một tác giả nào đó? Có một cách là thêm tác giả vào mảng tác phẩm, nhưng như thế sẽ thành ra phân vị trí các thành phần trong khi ta cần giữ cho mối liên hệ giữa tác giả với tác phẩm được bảo toàn.</p>
+
+<p>Cách tốt hơn là lấy <code>_id</code> của <em>tác giả</em>, rồi dùng <code>find()</code> để tìm trong trường tác giả xuyên suốt tác phẩm.</p>
+
+<pre class="brush: js"><code>Story
+.find({ author : bob._id })
+.exec(function (err, stories) {
+ if (err) return handleError(err);
+ // trả về tất cả các tác phẩm có id của Bob.
+});</code>
+</pre>
+</div>
+
+<p>Đến đây là đã đủ hết mọi thứ bạn cần biết trong<em> bài viết này rồi</em>. Để biết thêm thông tin chi tiết, mời bạn tham khảo <a href="http://mongoosejs.com/docs/populate.html">Population</a> (tài liệu của Mongoose).</p>
+
+<h3 id="Một_schemamô_hình_trên_một_tập_tin">Một schema/mô hình trên một tập tin</h3>
+
+<p>Dù bạn có thể tạo ra schema và mô hình theo bất cứ kiến trúc nào bạn thích, nhưng chúng tôi vẫn khuyến nghị nên định nghĩa chúng trên mỗi mô đun riêng rẽ (tập tin), rồi xuất mô hình ra ngoài. Làm như thế này này:</p>
+
+<pre class="brush: js"><code>// Tập tin: ./models/somemodel.js
+
+//Nhập Mongoose
+var mongoose = require('mongoose');
+
+//Định nghĩa một schema
+var Schema = mongoose.Schema;
+
+var SomeModelSchema = new Schema({
+ a_string : String,
+ a_date : Date,
+});
+
+<strong>//Xuất ra lớp mô hình "SomeModel"
+module.exports = mongoose.model('SomeModel', SomeModelSchema );</strong></code></pre>
+
+<p>Sau đó bạn có thể nhập và sử dụng mô hình ngay tắp lự ở bất cứ đâu. Dưới đây là cách bạn lấy ra mọi phần tử của mô hình.</p>
+
+<pre class="brush: js"><code>//Thê mới mô hình SomeModel thông qua lệnh require
+var SomeModel = require('../models/somemodel')
+
+// Sử dụng đối tượng SomeModel để tìm tất cả bản ghi của SomeModel
+SomeModel.find(callback_function);</code></pre>
+
+<h2 id="Thiết_lập_cơ_sở_dữ_liệu_MongoDB">Thiết lập cơ sở dữ liệu MongoDB</h2>
+
+<p>Giờ khi đã hiểu những gì Mongoose có thể làm và cách để ta có thể thiết kế một cơ sở dữ liệu, đến lúc thực hành trên trang web <em>LocalLibrary</em> rồi. Bước đầu tiên trong bài thực hành là tạo mới một cơ sở dữ liệu MongoDb để lưu trữ dữ liệu cho thư viện của chúng ta.</p>
+
+<p>Trong bài viết này ta sẽ sử dụng cơ sở dữ liệu nền điện toán đám mây của <a href="https://mlab.com/welcome/">mLab</a> (chọn kiểu "<a href="https://mlab.com/plans/pricing/">sandbox</a>" để dùng miễn phí). Cơ sở dữ liệu kiểu này không phù hợp dành cho các trang web thật vì nó không có dư thừa dữ liệu, nhưng lại rất hợp dành cho việc phát triển và xây dựng mẫu vật. Và bởi nó dễ dùng cũng như dễ thiết lập, và đừng quên rằng mLab là một trong những bên cung cấp khá nổi tiếng <em>cơ sở dữ liệu cung cấp dưới dạng dịch vụ</em> mà bạn có thể sẽ dùng cho dự án thật (vào thời điểm viết bài này bạn cũng có thể chọn các nhà cung cấp như <a href="https://www.compose.com/">Compose</a>, <a href="https://scalegrid.io/pricing.html">ScaleGrid</a> và <a href="https://www.mongodb.com/cloud/atlas">MongoDB Atlas</a>).</p>
+
+<div class="note">
+<p><strong>Lưu ý:</strong> Nếu bạn muốn thiết lập cơ sở dữ liệu MongoDb cục bộ thì hãy tìm và tải xuống <a href="https://www.mongodb.com/download-center">bản phù hợp với hệ thống của mình</a>. Phần còn lại khá là đơn giản, trừ phần URL của cơ sở dữ liệu mà bạn sẽ phải xác định nếu muốn kết nối tới.</p>
+</div>
+
+<p>Trước hết bạn cần <a href="https://mlab.com/signup/">tạo tài khoản</a> mLab (miễn phí, chỉ cần điền mẫu đăng ký là xong). </p>
+
+<p>Sau khi đã đăng nhập vào, bạn sẽ được chuyển tới <a href="https://mlab.com/home">trang chủ</a>:</p>
+
+<ol>
+ <li>Nhấn <strong>Create New</strong> trong phần <em>MongoDB Deployments</em>.<img alt="" src="https://mdn.mozillademos.org/files/14446/mLabCreateNewDeployment.png" style="height: 415px; width: 1000px;"></li>
+ <li>Nó sẽ mở ra màn hình <em>Cloud Provider Selection</em>.<br>
+ <img alt="MLab - screen for new deployment" src="https://mdn.mozillademos.org/files/15661/mLab_new_deployment_form_v2.png" style="height: 931px; width: 1297px;"><br>
+
+ <ul>
+ <li>Chọn SANDBOX (Free) plan trong phần Plan Type. </li>
+ <li>Chọn bất cứ nhà cung cấp nào trong phần <em>Cloud Provider</em>. Mỗi nhà cung cấp khác nhau ở các vùng lãnh thổ địa lý khác nhau (ở ngay dưới phần selected plan type).</li>
+ <li>Bấm nút <strong>Continue</strong>.</li>
+ </ul>
+ </li>
+ <li>Màn hình <em>Select Region</em> mở ra.
+ <p><img alt="Select new region screen" src="https://mdn.mozillademos.org/files/15662/mLab_new_deployment_select_region_v2.png" style="height: 570px; width: 1293px;"></p>
+
+ <ul>
+ <li>
+ <p>Chọn vùng lãnh thổ gần bạn nhất rồi nhấn <strong>Continue</strong>.</p>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>Màn hình <em>Final Details</em> mở ra.<br>
+ <img alt="New deployment database name" src="https://mdn.mozillademos.org/files/15663/mLab_new_deployment_final_details.png" style="height: 569px; width: 1293px;"></p>
+
+ <ul>
+ <li>
+ <p>Nhập tên cho cơ sở dữ liệu vừa tạo ra như <code>local_library</code> và chọn <strong>Continue</strong>.</p>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>Màn hình <em>Order Confirmation</em> sẽ mở lên.<br>
+ <img alt="Order confirmation screen" src="https://mdn.mozillademos.org/files/15664/mLab_new_deployment_order_confirmation.png" style="height: 687px; width: 1290px;"></p>
+
+ <ul>
+ <li>
+ <p>Nhấn <strong>Submit Order</strong> để tạo mới cơ sở dữ liệu.</p>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>Bạn sẽ được điều hướng về trang chủ. Nhấn vào cơ sở dữ liệu vừa thêm mới để xem chi tiết. Như bạn thấy đấy, cơ sở dữ liệu không có bất cứ bộ sưu tập nào (dữ liệu).<br>
+ <img alt="mLab - Database details screen" src="https://mdn.mozillademos.org/files/15665/mLab_new_deployment_database_details.png" style="height: 700px; width: 1398px;"><br>
+  <br>
+ URL mà bạn cần ở ngay đầu trang (trong phần khoanh đỏ). Để dùng được nó bạn phải tạo ra người dùng mới.</p>
+ </li>
+ <li>Nhấn vào tab <strong>Users</strong> và bấm nút <strong>Add database user</strong>.</li>
+ <li>Điền tên đăng nhập và mật khẩu (hai lần), và nhấn nút <strong>Create</strong>. Đừng bao giờ chọn <em>Make read only</em>.<br>
+ <img alt="" src="https://mdn.mozillademos.org/files/14454/mLab_database_users.png" style="height: 204px; width: 600px;"></li>
+</ol>
+
+<p>Giờ đã có cơ sở dữ liệu rồi, và cả URL (với tên đăng nhập và mật khẩu) đã sẵn sàng để truy xuất. Trông nó sẽ như thế này: <code>mongodb://your_user_namer:your_password@ds119748.mlab.com:19748/local_library</code>.</p>
+
+<h2 id="Cài_đặt_Mongoose">Cài đặt Mongoose</h2>
+
+<p>Mở command prompt và chuyển tới thư mục chứa <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/skeleton_website">trang web Local Library</a>. Nhập lệnh dưới để cài đặt Mongoose (và đống dependency của nó) và nó sẽ tự động thêm vào <strong>package.json</strong> của bạn, nếu bạn đã làm như với <a href="#Installing_Mongoose_and_MongoDB">Mongoose Primer</a> ở trên.</p>
+
+<pre class="brush: bash">npm install mongoose --save
+</pre>
+
+<h2 id="Kết_nối_tới_MongoDB">Kết nối tới MongoDB</h2>
+
+<p>Mở <strong>/app.js</strong> (trong project của bạn) và sao chép đống phía dưới để khai báo<em> đối tượng ứng dụng Express</em> (sau dòng <code>var app = express();</code>). Thay thế url của cơ sở dữ liệu ('<em>insert_your_database_url_here</em>') bằng URL của mình (như cái vừa tạo ra bằng<a href="#Setting_up_the_MongoDB_database"> mLab</a>).</p>
+
+<pre class="brush: js">//Thiết lập kết nối tới Mongoose
+var mongoose = require('mongoose');
+var mongoDB = '<em>insert_your_database_url_here</em>';
+mongoose.connect(mongoDB);
+mongoose.Promise = global.Promise;
+var db = mongoose.connection;
+db.on('error', console.error.bind(console, 'MongoDB connection error:'));</pre>
+
+<p>Như đã nói <a href="#Connecting_to_MongoDB">trong phần Mongoose primer phía trên</a>, đoạn code này tạo ra kết nối mặc định tới cơ sở dữ liệu và ràng buộc sự kiện lỗi (để in lỗi ra console). </p>
+
+<h2 id="Định_nghĩa_Schema_cho_LocalLibrary">Định nghĩa Schema cho LocalLibrary</h2>
+
+<p>Ta sẽ tạo ra mô đun cho từng mô hình, như <a href="#One_schemamodel_per_file">đã đề cập phía trên</a>. Bắt đầu bằng cách thêm mới thư mục trong thư mục gốc (<strong>/models</strong>) và tạo từng tập tin cho mỗi mô hình:</p>
+
+<pre>/express-locallibrary-tutorial //the project root
+ <strong>/models</strong>
+ <strong>author.js</strong>
+ <strong>book.js</strong>
+ <strong>bookinstance.js</strong>
+ <strong>genre.js</strong>
+</pre>
+
+<h3 id="Mô_hình_tác_giả">Mô hình tác giả</h3>
+
+<p>Sao chép đoạn code schema <code>Author</code> code bên dưới và dán vào tập tin <strong>./models/author.js</strong>. Scheme định nghĩa rằng một tác giả có kiểu <code>String</code> SchemaTypes cho hai trường họ và tên , bắt buộc và có giới hạn nhiều nhất 100 ký tự, và kiểu <code>Date</code> cho trường ngày sinh và ngày mất.</p>
+
+<pre class="brush: js">var mongoose = require('mongoose');
+
+var Schema = mongoose.Schema;
+
+var AuthorSchema = new Schema(
+ {
+ first_name: {type: String, required: true, max: 100},
+ family_name: {type: String, required: true, max: 100},
+ date_of_birth: {type: Date},
+ date_of_death: {type: Date},
+ }
+);
+
+<strong>// Tạo phương thức ảo cho tên đầy đủ
+AuthorSchema
+.virtual('name')
+.get(function () {
+ return this.family_name + ', ' + this.first_name;
+});</strong>
+
+// Phương thức ảo cho URL của tác giả
+AuthorSchema
+.virtual('url')
+.get(function () {
+ return '/catalog/author/' + this._id;
+});
+
+//xuất mô hình
+module.exports = mongoose.model('Author', AuthorSchema);
+
+</pre>
+
+<p>Ta vừa khai báo <a href="#Virtual_properties">phần ảo</a> cho AuthorSchema với tên là "url" trả về URL tuyệt đối bắt buộc để lấy ra phần tử nhất định của mô hình — ta sẽ dùng thuộc tính này trong mẫu mỗi khi cần lấy ra đường dẫn tới tác giả.</p>
+
+<div class="note">
+<p><strong>Lưu ý:</strong> Khai báo URL bằng hàm ảo trong schema là ý tưởng tốt bởi vì URL sẽ chỉ cần thay đổi tại một nơi.<br>
+ Vào lúc này các URL sẽ không thể hoạt động, ta chưa đặt ra các route nào để dẫn lối cho từng phần tử của mô hình. Ta sẽ làm việc này trong các bài viết sau!</p>
+</div>
+
+<p>Sau khi đã xong thì ta xuất mô hình ra thôi.</p>
+
+<h3 id="Mô_hình_sách">Mô hình sách</h3>
+
+<p>Sao chép đoạn code schema <code>Book</code> bên dưới và dán nó vào tập tin <strong>./models/book.js</strong>. Làm tương tự đối như với tác giả — ta vừa khai báo một schema có nhiều trường String và một phần ảo để lấy URL của các bản ghi sách, sau đó thì xuất nó ra.</p>
+
+<pre class="brush: js">var mongoose = require('mongoose');
+
+var Schema = mongoose.Schema;
+
+var BookSchema = new Schema(
+ {
+ title: {type: String, required: true},
+ <strong> author: {type: Schema.ObjectId, ref: 'Author', required: true},</strong>
+ summary: {type: String, required: true},
+ isbn: {type: String, required: true},
+ <strong> genre: [{type: Schema.ObjectId, ref: 'Genre'}]</strong>
+ }
+);
+
+// Tạo hàm ảo lấy URL của sách
+BookSchema
+.virtual('url')
+.get(function () {
+ return '/catalog/book/' + this._id;
+});
+
+//Xuất mô hình
+module.exports = mongoose.model('Book', BookSchema);
+</pre>
+
+<p>Sự khác biệt chính là ta vừa tạo ra hai mối liên quan đến sách:</p>
+
+<ul>
+ <li>author được trỏ tới mô hình đối tượng <code>Author</code>, và bắt buộc.</li>
+ <li>genre được trỏ tới một mảng mô hình đối tượng <code>Genre</code>. Ta vẫn chưa định nghĩa đối tượng này!</li>
+</ul>
+
+<h3 id="Mô_hình_BookInstance">Mô hình BookInstance</h3>
+
+<p>Cuối cùng sao chép đoạn code schema <code>BookInstance</code> bên dưới và dán nó vào tập tin <strong>./models/bookinstance.js</strong>. <code>BookInstance</code> đại diện cho số bản sách mà ai đó mượn, và bao gồm thông itn về thời điểm sách  về hoặc hạn trả sách dự kiến, "đánh dấu" hoặc lấy chi tiết phiên bản.</p>
+
+<pre class="brush: js">var mongoose = require('mongoose');
+
+var Schema = mongoose.Schema;
+
+var BookInstanceSchema = new Schema(
+ {
+ book: { type: Schema.ObjectId, ref: 'Book', required: true }, //reference to the associated book
+ imprint: {type: String, required: true},
+ status: {type: String, required: true, <strong>enum: ['Available', 'Maintenance', 'Loaned', 'Reserved']</strong>, <strong>default: 'Maintenance'</strong>},
+ due_back: {type: Date, <strong>default: Date.now</strong>}
+ }
+);
+
+// Lấy ra URL của bookinstance
+BookInstanceSchema
+.virtual('url')
+.get(function () {
+ return '/catalog/bookinstance/' + this._id;
+});
+
+//Xuất mô hình
+module.exports = mongoose.model('BookInstance', BookInstanceSchema);</pre>
+
+<p>Các thuộc tính mới được thêm vào trong này nằm trong phần trường dữ liệu:</p>
+
+<ul>
+ <li><code>enum</code>: Cho phép ta đặt giá trị chấp nhận được cho xâu truyền vào. Trong trường hợp này ta dùng nó để xác định trạng thái còn sẵn của sách (sử dụng enum sẽ giúp ta tránh khỏi các lỗi chính tả hoặc khai khống giá trị cho trạng thái)</li>
+ <li><code>default</code>: Ta dùng default để đặt giá trị mặc định cho những bookinstances mới khởi tạo để bảo trì <code>due_back</code> mặc định <code>now</code> (lưu ý cách gọi hàm Date khi thiết lập ngày giờ!)</li>
+</ul>
+
+<p>Những schema còn lại làm tương tự.</p>
+
+<h3 id="Mô_hình_thể_loại_-_thử_thách!">Mô hình thể loại - thử thách!</h3>
+
+<p>Mở tập tin <strong>./models/genre.js</strong> của bạn lên và tạo mới một schema để lưu lại thể loại sách (các kiểu sách như là truyện tiểu thuyết, tư liệu lịch sử...).</p>
+
+<p>Cách định nghĩa cũng giống như các mô hình ở trên:</p>
+
+<ul>
+ <li>Mô hình nên có một <code>String</code> SchemaType tên là <code>name</code> để mô tả thể loại.</li>
+ <li>Tên này phải bắt buộc và có từ 3 đến 100 kí tự.</li>
+ <li>Tạo một <a href="#Virtual_properties">phương thức ảo</a> cho URL của thể loại, để tên là <code>url</code>.</li>
+ <li>Xuất mô hình.</li>
+</ul>
+
+<h2 id="Kiểm_thử_—_tạo_ra_vài_bản_ghi">Kiểm thử — tạo ra vài bản ghi</h2>
+
+<p>Xong xuôi rồi đó. Giờ ta đã có tất cả mô hình!</p>
+
+<p>Để có thể kiểm thử mô hình (và để tạo ra vài sách mẫu và một số thứ khác ta sẽ dùng trong bài viết sau) ta sẽ chạy một đoạn kịch bản <em>independent</em> để tạo ra các bản ghi cho từng mô hình:</p>
+
+<ol>
+ <li>Tải về (hoặc tạo mới) tập tin <a href="https://raw.githubusercontent.com/hamishwillee/express-locallibrary-tutorial/master/populatedb.js">populatedb.js</a> trong thư mục <em>express-locallibrary-tutorial</em> (đồng cấp với <code>package.json</code>).
+
+ <div class="note">
+ <p><strong>Lưu ý:</strong> Bạn không cần hiểu cách thức <a href="https://raw.githubusercontent.com/hamishwillee/express-locallibrary-tutorial/master/populatedb.js">populatedb.js</a> hoạt động; nó chỉ thêm dữ liệu mẫu vào trong cơ sở dữ liệu thôi.</p>
+ </div>
+ </li>
+ <li>Nhập lệnh phía dưới vào trong thư mục chứa project để cài đặt mô-đun <em>async</em> để có thể chạy được đoạn kịch bản (ta sẽ bàn về việc này trong bài tiếp theo, )
+ <pre class="brush: bash">npm install async --save</pre>
+ </li>
+ <li>Chạy đoạn kịch bản bằng node trong command prompt của bạn, truyền vào URL của cơ sở dữ liệu MongoDB (như cái bạn đã thay thế cho <em>insert_your_database_url_here</em>, trong <code>app.js</code> phía trên):
+ <pre class="brush: bash">node populatedb &lt;your mongodb url&gt;​​​​</pre>
+ </li>
+ <li>Đoạn code sẽ chạy thành công và in ra những vật được tạo ra trên màn console.</li>
+</ol>
+
+<div class="note">
+<p><strong>Mẹo:</strong> Lên cơ sở dữ liệu của bạn trên <a href="https://mlab.com/home">mLab</a>. Giờ bạn có thể chui vào bộ sưu tập Books, Authors, Genres và BookInstances, và kiểm tra các tài liệu vừa được tạo.</p>
+</div>
+
+<h2 id="Tóm_lại">Tóm lại</h2>
+
+<p>Trong bài viết này ta học một chút về cơ sở dữ liệu và ORMs trên Node/Express, và cách để định nghĩa schema và mô hình của Mongoose. Sau đó ta đã thực hành thiết kế và triển khai các mô hình <code>Book</code>, <code>BookInstance</code>, <code>Author</code> và <code>Genre</code> cho trang web <em>LocalLibrary</em>.</p>
+
+<p>Sau cùng ta kiểm thử những gì vừa viết ra bằng cách tạo một đống các phần tử (bằng cách sử dụng một đoạn mã kịch bản). Trong bài tiếp theo ta sẽ học cách tạo các trang để trình bày các thứ.</p>
+
+<h2 id="Đọc_thêm">Đọc thêm</h2>
+
+<ul>
+ <li><a href="https://expressjs.com/en/guide/database-integration.html">Database integration</a> (tài liệu của Express)</li>
+ <li><a href="http://mongoosejs.com/">Mongoose website</a> (tài liệu của Mongoose)</li>
+ <li><a href="http://mongoosejs.com/docs/guide.html">Mongoose Guide</a> (tài liệu của Mongoose)</li>
+ <li><a href="http://mongoosejs.com/docs/validation.html">Validation</a> (tài liệu của Mongoose)</li>
+ <li><a href="http://mongoosejs.com/docs/schematypes.html">Schema Types</a> (tài liệu của Mongoose)</li>
+ <li><a href="http://mongoosejs.com/docs/models.html">Models</a> (tài liệu của Mongoose)</li>
+ <li><a href="http://mongoosejs.com/docs/queries.html">Queries</a> (tài liệu của Mongoose)</li>
+ <li><a href="http://mongoosejs.com/docs/populate.html">Population</a> (tài liệu của Mongoose)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/skeleton_website", "Learn/Server-side/Express_Nodejs/routes", "Learn/Server-side/Express_Nodejs")}}</p>
+
+<p> </p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Introduction">Express/Node introduction</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/development_environment">Setting up a Node (Express) development environment</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">Express Tutorial: The Local Library website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/skeleton_website">Express Tutorial Part 2: Creating a skeleton website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose">Express Tutorial Part 3: Using a Database (with Mongoose)</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/routes">Express Tutorial Part 4: Routes and controllers</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data">Express Tutorial Part 5: Displaying library data</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/forms">Express Tutorial Part 6: Working with forms</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/deployment">Express Tutorial Part 7: Deploying to production</a></li>
+</ul>
+
+<p> </p>
diff --git a/files/vi/learn/server-side/express_nodejs/tutorial_local_library_website/index.html b/files/vi/learn/server-side/express_nodejs/tutorial_local_library_website/index.html
new file mode 100644
index 0000000000..3f1fa21d2f
--- /dev/null
+++ b/files/vi/learn/server-side/express_nodejs/tutorial_local_library_website/index.html
@@ -0,0 +1,89 @@
+---
+title: 'Express Tutorial: The Local Library website'
+slug: Learn/Server-side/Express_Nodejs/Tutorial_local_library_website
+translation_of: Learn/Server-side/Express_Nodejs/Tutorial_local_library_website
+---
+<div>
+<p>{{LearnSidebar}}</p>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/development_environment", "Learn/Server-side/Express_Nodejs/skeleton_website", "Learn/Server-side/Express_Nodejs")}}</p>
+</div>
+
+<p class="summary">Đây là bài đầu tiên sẽ giải thích những gì chúng ta sẽ học và giới thiệu tổng quan về dự án thư viên cục bộ mà chúng ta sẽ cải tiến trong suốt khoá học.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Điều kiện tiền quyết:</th>
+ <td>Đọc bài  <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Introduction">Express Introduction</a>. Sau đó bạn cũng cẩn phải cài đặt môi trường phát triển Node <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/development_environment">set up a Node development environment</a>. </td>
+ </tr>
+ <tr>
+ <th scope="row">Mục tiêu:</th>
+ <td>Để giới thiệu ví dụ sẽ được sử dụng trong bài học và giúp người đọc hiểu những chủ đề sẽ được dạy.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Khái_quát">Khái quát</h2>
+
+<p>Chào mứng đến với bộ tài liệu sử dụng Express(Node) để xây dựng một trang web quản lý các chỉ mục trong thư viện.</p>
+
+<p>Trong loạt bài học này, bạn sẽ được day:</p>
+
+<ul>
+ <li>Sử dụng công cụ <em>trang web Application Generator</em> để tạo ra cái sườn cho một website và ứng dụng.</li>
+ <li>Start và stop Node web server.</li>
+ <li>Sử dụng database để lưu trữ dữ liệu của bạn.</li>
+ <li>Tạo những cái routes cho những đường dẫn khác nhau và template ("views") để hiển thị dữ liệu dưới đạng HTML trong trình duyệt.</li>
+ <li>Làm việc với form.</li>
+ <li>Triển khai ứng dụng ra thực tế.</li>
+</ul>
+
+<p>Nếu bạn đã học những chủ đề này rồi và lướt sơ qua các phần khác. Tới cuối loạt bài học này bạn sẽ đủ hiểu biết để phát triển một ứng dụng đơn giản với Express.</p>
+
+<h2 id="LocalLibrary_website">LocalLibrary website</h2>
+
+<p><em>LocalLibrary</em> là tên của website mà bạn sẽ tạo ra và cải tiến trong loạt các bài học này. Như bạn mong đợi, mục tiêu của trang web là cung cấp một danh mục trực tuyến cho một thư viện cục bộ nhỏ, nơi mà người dùng có thể truy cập những quyển sách có sẵn và quản lý tài khoản của họ.</p>
+
+<p>Ví dụ này được lựa chọn rất cẩn thận bởi vì nó có thể được điều chỉnh để chỉ hiển thị những chức năng vừa phải để có thể ứng dụng hầu hết các chức năng của Express. Quan trọng hơn nữa, nó giúp chúng tôi vẽ ra con đường để hướng dẫn các chức năng cần thiệt trong việc phát triển bất kỳ website nào :</p>
+
+<ul>
+ <li>Trong các bài đầu tiên, chúng tôi chỉ tạo ra một thư viện đơn giản, mà người dùng có thể tìm kiếm những quyển sách sẵn có. Điều này dạy chúng ta cách đọc và hiển thị nội dung từ một cơ sở dữ liệu, chức năng thường có trong lập trình web.</li>
+ <li>Như chúng tôi đã cân nhấc, ứng dụng thư viện còn có các chức năng nâng cao của việc phát triển web. Ví dụ chức năng thêm vào một quyển sách mới giúp bạn học được cách làm việc với Form và chứng thực người dùng</li>
+</ul>
+
+<p>Tuy đây là một ví dụ có tính mở rộng cao, nhưng nó được gọi là "LocalLibrary" bởi vì chúng tôi hy vọng chỉ để thể hiện những thông tin tối thiểu để giúp bạn bắt đầu với Express một cách nhanh chóng. Cho nên chúng ta sẽ lưu thông tin về sách, bản sao sách, tác giả và các thông tin mấu chốt khác, mà chúng ta không lưu thông tin về những phần khác thư viện như việc cho mượn hay cơ sở hạ tầng để hỗ trợ đặt trang web cho thư viện hay những chức năng cho một "thư viện lớn".</p>
+
+<h2 id="Khi_gặp_khó_khăn_thì_tham_khảo_ở_đâu">Khi gặp khó khăn, thì tham khảo ở đâu? </h2>
+
+<p>Trong suốt tài liệu chúng tôi sẽ cung cấp những đoạn mã nguồn mà bạn có thể tham khảo ở mỗi phần, và có nhiều mã nguồn khác mà chúng tôi hi vọng bạn sẽ mở rộng nó.</p>
+
+<p>Nếu bạn bí quá thì có thể tham khảo toàn bộ mã nguồn của website <a href="https://github.com/mdn/express-locallibrary-tutorial">trên Github</a>.</p>
+
+<div class="note">
+<p><strong>Chú ý: </strong> Những phiên bản của node, Express và những modules khác mà tài liệu này sử dụng được liệt kê ở trong <a href="https://github.com/mdn/express-locallibrary-tutorial/blob/master/package.json">package.json</a>.</p>
+</div>
+
+<h2 id="Tổng_Kết">Tổng Kết</h2>
+
+<p>Bây giờ bạn đã biết về dự án LocalLibrary, giờ thì bắt đầu tạo <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/skeleton_website">cấu trúc dự án</a> nào.</p>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/development_environment", "Learn/Server-side/Express_Nodejs/skeleton_website", "Learn/Server-side/Express_Nodejs")}}</p>
+
+<p> </p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Introduction">Express/Node introduction</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/development_environment">Setting up a Node (Express) development environment</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">Express Tutorial: The Local Library website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/skeleton_website">Express Tutorial Part 2: Creating a skeleton website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose">Express Tutorial Part 3: Using a Database (with Mongoose)</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/routes">Express Tutorial Part 4: Routes and controllers</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data">Express Tutorial Part 5: Displaying library data</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/forms">Express Tutorial Part 6: Working with forms</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/deployment">Express Tutorial Part 7: Deploying to production</a></li>
+</ul>
+
+<p> </p>
diff --git a/files/vi/learn/server-side/first_steps/index.html b/files/vi/learn/server-side/first_steps/index.html
new file mode 100644
index 0000000000..95ddf775ab
--- /dev/null
+++ b/files/vi/learn/server-side/first_steps/index.html
@@ -0,0 +1,46 @@
+---
+title: Các bước đầu tiên để lập trình trang web phía máy chủ
+slug: Learn/Server-side/First_steps
+tags:
+ - Giới thiệu
+ - Hướng dẫn
+ - Học
+ - Lập trình máy chủ
+ - Ngôn ngữ lập trình
+ - Người Mới Bắt Đầu
+translation_of: Learn/Server-side/First_steps
+---
+<div>{{LearnSidebar}}</div>
+
+<p>Trong mô-đun này chúng ta tìm cầu trả lời về một vài câu hỏi chức năng về lập trình phía máy chủ<span class="seoSummary"> — "Nó là gì?", "Nó khác như nào so với lập trình phía máy khách ?", và "Tại sao nó lại hữu ích?".</span> Tiếp theo chúng ta tìm hiểu tổng quan về một số framework (Một nền tảng bao gồm các tệp/thư mục tạo sẵn được quy chuẩn khi sử dụng nó để lập trình khi tạo một dự án mới) phổ biến để tạo web phía máy chủ, cùng với hướng dẫn phù hợp nhất để lựa chọn framework phù hợp để tạo trang web đầu tiên của bạn. Cuối cùng chúng ta tìm hiểu bài viết cấp cao về bảo mật máy chủ web.</p>
+
+<h2 id="Kiến_thức_yêu_cầu">Kiến thức yêu cầu </h2>
+
+<p>Trước khi bắt đầu mô-dun này, bạn không cần phải có bất kỳ hiểu biết nào về lập trình phía máy chủ, hoặc bất kỳ ngôn ngữ lập trình nào khác. </p>
+
+<p>Tuy nhiên, bạn cần hiểu về cách web làm việc. Chúng tôi đề xuất bạn nên đọc các chủ đề này trước khi bắt đầu:</p>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Common_questions/What_is_a_web_server">Một máy chủ web là gì?</a></li>
+ <li><a href="/en-US/docs/Learn/Common_questions/What_software_do_I_need">Phần mềm nào cần thiết để xây dựng một trang web?</a></li>
+ <li><a href="/en-US/docs/Learn/Common_questions/Upload_files_to_a_web_server">Làm thế nào để đẩy tập tin lên một máy chủ web?</a></li>
+</ul>
+
+<p>Với các hiểu biết cơ bản, bạn sẽ sẵn sàng để làm việc theo cách của mình thông qua các mô-dun trong phần này. </p>
+
+<h2 id="Hướng_dẫn">Hướng dẫn</h2>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/Server-side/First_steps/Introduction">Giới thiệu về phía máy chủ</a> </dt>
+ <dd>Chào mừng bạn đến với khóa học lập trình phía máy chủ của MDN cho người mới bắt đầu! <font>Trong bài viết đầu tiên này, chúng tôi xem xét lập trình phía máy chủ từ cấp độ cao, trả lời các câu hỏi như "Nó là gì?", "Nó khác với lập trình phía máy khách như thế nào?" Và "Tại sao nó lại hữu ích như vậy?" . </font><font>Sau khi đọc bài viết này, bạn sẽ hiểu sức mạnh bổ sung có sẵn cho các trang web thông qua mã hóa phía máy chủ</font>.</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview">Tổng quan về Khách-Chủ</a> </dt>
+ <dd><font>Bây giờ bạn đã biết mục đích và lợi ích tiềm năng của lập trình phía máy chủ, chúng ta sẽ kiểm tra chi tiết điều gì xảy ra khi máy chủ nhận được "yêu cầu động" từ trình duyệt. </font><font>Vì mã phía máy chủ của hầu hết các trang web xử lý các yêu cầu và phản hồi theo cách tương tự, điều này sẽ giúp bạn hiểu những gì bạn cần làm khi viết mã của riêng mình. </font></dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/First_steps/Web_frameworks">Các framework phía máy chủ</a></dt>
+ <dd><font>Bài viết cuối cùng cho bạn thấy một ứng dụng web phía máy chủ cần làm gì để đáp ứng các yêu cầu từ trình duyệt web. </font><font>Bây giờ chúng tôi chỉ ra cách các khung web có thể đơn giản hóa các tác vụ này và giúp bạn chọn khung phù hợp cho ứng dụng web phía máy chủ đầu tiên của bạn.</font></dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/First_steps/Website_security">Bảo mật trang web</a> </dt>
+ <dd><font>Bảo mật trang web đòi hỏi sự cảnh giác trong tất cả các khía cạnh của thiết kế và sử dụng. </font><font>Bài viết giới thiệu này sẽ không làm bạn thành một chuyên gia bảo mật trang web, nhưng nó sẽ giúp bạn hiểu các bước quan trọng đầu tiên bạn có thể thực hiện để bảo vệ ứng dụng web của mình trước các mối đe dọa phổ biến nhất.</font></dd>
+</dl>
+
+<h2 id="Đánh_giá">Đánh giá</h2>
+
+<p><font>Mô-đun "tổng quan" này không có bất kỳ đánh giá nào vì chúng tôi chưa hiển thị cho bạn bất kỳ mã nào. </font><font>Chúng tôi hy vọng rằng tại thời điểm này, bạn hiểu rõ về loại chức năng nào bạn có thể cung cấp bằng lập trình phía máy chủ và bạn đã đưa ra quyết định về khung web phía máy chủ nào bạn sẽ sử dụng để tạo trang web đầu tiên của mình.</font></p>
diff --git a/files/vi/learn/server-side/first_steps/introduction/index.html b/files/vi/learn/server-side/first_steps/introduction/index.html
new file mode 100644
index 0000000000..9594c42833
--- /dev/null
+++ b/files/vi/learn/server-side/first_steps/introduction/index.html
@@ -0,0 +1,228 @@
+---
+title: Introduction to the server side
+slug: Learn/Server-side/First_steps/Introduction
+translation_of: Learn/Server-side/First_steps/Introduction
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{NextMenu("Learn/Server-side/First_steps/Client-Server_overview", "Learn/Server-side/First_steps")}}</div>
+
+<p class="summary"><span class="seoSummary">Chào mừng bạn đến với khóa học lập trình phía máy chủ của người mới bắt đầu MDN! Trong bài viết đầu tiên này, chúng tôi xem xét lập trình phía máy chủ từ cấp độ cao, trả lời các câu hỏi như "nó là gì?", "Nó khác với lập trình phía máy khách như thế nào?" Và "tại sao nó lại hữu ích như vậy?" . Sau khi đọc bài viết này, bạn sẽ hiểu sức mạnh bổ sung có sẵn cho các trang web thông qua mã hóa phía máy chủ.</span></p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Điều kiện:</th>
+ <td>Kiến thức cơ bản về máy tính. Một sự hiểu biết cơ bản về những gì là một máy chủ web.</td>
+ </tr>
+ <tr>
+ <th scope="row">Mục tiêu:</th>
+ <td>Để làm quen với lập trình phía máy chủ là gì, nó có thể làm gì và nó khác với lập trình phía máy khách như thế nào.</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Hầu hết các trang web quy mô lớn sử dụng mã phía máy chủ để hiển thị động các dữ liệu khác nhau khi cần, các dữ liệu thường rút ra khỏi cơ sở dữ liệu được lưu trữ trên máy chủ và được gửi đến máy khách để được hiển thị thông qua một số mã (ví dụ: HTML và JavaScript).</p>
+
+<p>Có lẽ lợi ích đáng kể nhất của mã phía máy chủ là nó cho phép bạn điều chỉnh nội dung trang web cho từng người dùng. Các trang web động có thể làm nổi bật nội dung phù hợp hơn dựa trên sở thích và thói quen của người dùng. Nó cũng có thể làm cho các trang web dễ sử dụng hơn bằng cách lưu trữ thông tin và sở thích cá nhân - ví dụ: sử dụng lại chi tiết thẻ tín dụng được lưu trữ để hợp lý hóa các khoản thanh toán tiếp theo.</p>
+
+<p>Nó thậm chí có thể cho phép tương tác với người dùng của trang web, gửi thông báo và cập nhật qua email hoặc qua các kênh khác. Tất cả các khả năng này cho phép tham gia sâu hơn nhiều với người dùng.</p>
+
+<p>Trong thế giới phát triển web hiện đại, việc tìm hiểu về phát triển phía máy chủ rất được khuyến khích.</p>
+
+<h2 id="Lập_trình_trang_web_phía_máy_chủ_là_gì">Lập trình trang web phía máy chủ là gì?</h2>
+
+<p>Trình duyệt web giao tiếp với máy chủ web bằng cách sử dụng <strong>H</strong>yper<strong>T</strong>ext <strong>T</strong>ransfer <strong>P</strong>rotocol ({{glossary("HTTP")}}). Khi bạn nhấp vào một liên kết trên một trang web, gửi biểu mẫu hoặc chạy tìm kiếm, một <strong>yêu cầu</strong> <strong>HTTP</strong> được gửi từ trình duyệt của bạn đến máy chủ mục tiêu.</p>
+
+<p>Yêu cầu bao gồm một URL xác định tài nguyên bị ảnh hưởng, một phương thức xác định hành động được yêu cầu (ví dụ để lấy, xóa hoặc đăng tài nguyên) và có thể bao gồm thông tin bổ sung được mã hóa trong các tham số URL (các cặp giá trị trường được gửi qua <a href="https://en.wikipedia.org/wiki/Query_string">truy vấn chuỗi</a>), dưới dạng dữ liệu POST (dữ liệu được gửi bởi <a href="https://wiki.developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST">phương thức HTTP POST</a> ), hoặc trong các {{glossary("Cookie", "cookies")}} được liên kết.</p>
+
+<p>Các máy chủ web chờ tin nhắn yêu cầu của khách hàng, xử lý chúng khi chúng đến và trả lời trình duyệt web bằng tin nhắn <strong>phản hồi HTTP</strong>. Phản hồi chứa một dòng trạng thái cho biết liệu yêu cầu có thành công hay không (ví dụ:  "HTTP/1.1 200 OK" for success). </p>
+
+<p>Phần chính của phản hồi thành công đối với yêu cầu sẽ chứa tài nguyên được yêu cầu (ví dụ: trang HTML mới hoặc hình ảnh, v.v.), sau đó có thể được trình duyệt web hiển thị.</p>
+
+<h3 id="Trang_web_tĩnh">Trang web tĩnh</h3>
+
+<p>Sơ đồ bên dưới hiển thị kiến trúc máy chủ web cơ bản cho một <em>trang tĩnh</em> (một trang tĩnh là một trang trả về cùng một nội dung được mã hóa cứng từ máy chủ bất cứ khi nào một tài nguyên cụ thể được yêu cầu). Khi người dùng muốn điều hướng đến một trang, trình duyệt sẽ gửi yêu cầu "GET" HTTP chỉ định URL của nó.</p>
+
+<p>Máy chủ lấy tài liệu được yêu cầu từ hệ thống tệp của nó và trả về phản hồi HTTP có chứa tài liệu và <a href="https://wiki.developer.mozilla.org/en-US/docs/Web/HTTP/Status#Successful_responses">trạng thái thành công</a> (thường là 200 OK). Nếu một số lý do không thể truy xuất tệp, một trạng thái lỗi được trả về (xem <a href="https://wiki.developer.mozilla.org/en-US/docs/Web/HTTP/Status#Client_error_responses">phản hồi lỗi máy khách</a> và <a href="https://wiki.developer.mozilla.org/en-US/docs/Web/HTTP/Status#Server_error_responses">phản hồi lỗi máy chủ</a>).</p>
+
+<p><img alt="A simplified diagram of a static web server." src="https://mdn.mozillademos.org/files/13841/Basic%20Static%20App%20Server.png" style="height: 223px; width: 800px;"></p>
+
+<h3 id="Trang_web_động">Trang web động</h3>
+
+<p>Trang web động là một trong đó một số nội dung phản hồi được tạo <em>động</em>, chỉ khi cần. Trên trang web động, các trang HTML thường được tạo bằng cách chèn dữ liệu từ cơ sở dữ liệu vào trình giữ chỗ trong các mẫu HTML (đây là cách lưu trữ lượng lớn nội dung hiệu quả hơn nhiều so với sử dụng trang web tĩnh).</p>
+
+<p>Trang web động có thể trả về dữ liệu khác nhau cho một URL dựa trên thông tin được cung cấp bởi người dùng hoặc tùy chọn được lưu trữ và có thể thực hiện các hoạt động khác như một phần của việc trả lại phản hồi (ví dụ: gửi thông báo).</p>
+
+<p>Hầu hết các mã để hỗ trợ một trang web động phải chạy trên máy chủ. Tạo mã này được gọi là "<strong>lập trình phía máy chủ</strong>" (hoặc đôi khi là "<strong>kịch bản phía sau</strong>").</p>
+
+<p>Sơ đồ dưới đây cho thấy một kiến trúc đơn giản cho một <em>trang web động</em>. Như trong sơ đồ trước, các trình duyệt gửi yêu cầu HTTP đến máy chủ, sau đó máy chủ xử lý các yêu cầu và trả về các phản hồi HTTP thích hợp.</p>
+
+<p>Các yêu cầu đối với tài nguyên tĩnh được xử lý theo cách tương tự như đối với các trang web tĩnh (tài nguyên tĩnh là bất kỳ tệp nào không thay đổi về cách thức: CSS, JavaScript, Hình ảnh, tệp PDF được tạo trước, v.v.).</p>
+
+<p><img alt="A simplified diagram of a web server that uses server-side programming to get information from a database and construct HTML from templates. This is the same diagram as is in the Client-Server overview." src="https://mdn.mozillademos.org/files/13839/Web%20Application%20with%20HTML%20and%20Steps.png"></p>
+
+<p>Yêu cầu tài nguyên động thay vào đó được chuyển tiếp (2) sang mã phía máy chủ (được hiển thị trong sơ đồ dưới dạng <em>Ứng dụng web</em>). Đối với "yêu cầu động", máy chủ diễn giải yêu cầu, đọc thông tin bắt buộc từ cơ sở dữ liệu (3), kết hợp dữ liệu được truy xuất với các mẫu HTML (4) và gửi lại phản hồi có chứa HTML được tạo (5,6). </p>
+
+<div>
+<h2 id="Các_chương_trình_phía_máy_chủ_và_phía_máy_khách_có_giống_nhau_không">Các chương trình phía máy chủ và phía máy khách có giống nhau không?</h2>
+</div>
+
+<p>Bây giờ chúng ta hãy chú ý đến mã liên quan đến lập trình phía máy chủ và phía máy khách. Trong mỗi trường hợp, mã là khác nhau đáng kể:</p>
+
+<ul>
+ <li>Chúng có những mục đích và mối quan tâm khác nhau.</li>
+ <li>Chúng thường không sử dụng cùng một ngôn ngữ lập trình (ngoại lệ là JavaScript, có thể được sử dụng ở phía máy chủ và phía máy khách).</li>
+ <li>Chúng chạy bên trong các môi trường hệ điều hành khác nhau.</li>
+</ul>
+
+<p>Mã chạy trong trình duyệt được gọi là <strong>mã phía máy khách</strong> và chủ yếu liên quan đến việc cải thiện giao diện và hành vi của một trang web được hiển thị. Điều này bao gồm lựa chọn và tạo kiểu các thành phần UI, tạo bố cục, điều hướng, xác thực mẫu, v.v ... Ngược lại, lập trình trang web phía máy chủ chủ yếu liên quan đến việc chọn <em>nội dung</em> nào được trả về trình duyệt để đáp ứng yêu cầu. Mã phía máy chủ xử lý các tác vụ như xác thực dữ liệu và yêu cầu đã gửi, sử dụng cơ sở dữ liệu để lưu trữ và truy xuất dữ liệu và gửi dữ liệu chính xác đến máy khách theo yêu cầu.</p>
+
+<p>Mã phía máy khách được viết bằng <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/HTML">HTML</a>, <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/CSS">CSS</a> và <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript">JavaScript</a> - nó được chạy bên trong trình duyệt web và có ít hoặc không có quyền truy cập vào hệ điều hành bên dưới (bao gồm quyền truy cập hạn chế vào hệ thống tệp).</p>
+
+<p>Các nhà phát triển web không thể kiểm soát trình duyệt mà mọi người dùng có thể đang sử dụng để xem trang web - trình duyệt cung cấp mức độ tương thích không nhất quán với các tính năng mã phía máy khách và một phần thách thức của lập trình phía máy khách là xử lý các khác biệt trong hỗ trợ trình duyệt một cách duyên dáng.</p>
+
+<p>Mã phía máy chủ có thể được viết bằng bất kỳ số ngôn ngữ lập trình nào - ví dụ về các ngôn ngữ web phía máy chủ phổ biến bao gồm PHP, Python, Ruby, C # và NodeJS (JavaScript). Mã phía máy chủ có toàn quyền truy cập vào hệ điều hành máy chủ và nhà phát triển có thể chọn ngôn ngữ lập trình (và phiên bản cụ thể) mà họ muốn sử dụng.</p>
+
+<p>Các nhà phát triển thường viết mã của họ bằng cách sử dụng <strong>các khung web</strong>. Các khung web là tập hợp các hàm, đối tượng, quy tắc và các cấu trúc mã khác được thiết kế để giải quyết các vấn đề phổ biến, tăng tốc độ phát triển và đơn giản hóa các loại nhiệm vụ khác nhau phải đối mặt trong một miền cụ thể.</p>
+
+<p>Một lần nữa, trong khi cả mã phía máy khách và máy chủ đều sử dụng các khung, các miền rất khác nhau và do đó là các khung. Các khung web phía máy khách đơn giản hóa các tác vụ bố trí và trình bày trong khi các khung web phía máy chủ cung cấp rất nhiều chức năng máy chủ web phổ biến mà bạn có thể phải tự thực hiện (ví dụ: hỗ trợ phiên, hỗ trợ người dùng và xác thực, truy cập cơ sở dữ liệu dễ dàng, thư viện templating, vv).</p>
+
+<div class="note">
+<p><strong>Note</strong>: Client-side frameworks thường được sử dụng để giúp tăng tốc độ phát triển mã phía máy khách, nhưng bạn cũng có thể chọn viết tất cả mã bằng tay; thực tế, viết mã bằng tay có thể nhanh hơn và hiệu quả hơn nếu bạn chỉ cần một giao diện người dùng trang web nhỏ, đơn giản.</p>
+
+<p><br>
+ Ngược lại, bạn gần như sẽ không bao giờ xem xét việc viết thành phần phía máy chủ của ứng dụng web mà không có framework — thực hiện một tính năng quan trọng như máy chủ HTTP thực sự khó thực hiện từ đầu khi nói Python, nhưng các web frameworks như Django cung cấp một của hộp, cùng với các công cụ rất hữu ích khác.</p>
+</div>
+
+<div>
+<h2 id="Bạn_có_thể_làm_gì_ở_phía_máy_chủ">Bạn có thể làm gì ở phía máy chủ?</h2>
+
+<p>Lập trình phía máy chủ rất hữu ích vì nó cho phép chúng tôi cung cấp <em>hiệu quả</em> thông tin phù hợp cho từng người dùng và từ đó tạo ra trải nghiệm người dùng tốt hơn nhiều.</p>
+</div>
+
+<p>Các công ty như Amazon sử dụng lập trình phía máy chủ để xây dựng kết quả tìm kiếm cho sản phẩm, đưa ra đề xuất sản phẩm được nhắm mục tiêu dựa trên sở thích của khách hàng và thói quen mua trước đó, đơn giản hóa việc mua hàng, v.v.</p>
+
+<p>Các ngân hàng sử dụng lập trình phía máy chủ để lưu trữ thông tin tài khoản và chỉ cho phép người dùng được ủy quyền xem và thực hiện giao dịch. Các dịch vụ khác như Facebook, Twitter, Instagram và Wikipedia sử dụng lập trình phía máy chủ để làm nổi bật, chia sẻ và kiểm soát quyền truy cập vào nội dung thú vị.</p>
+
+<p>Một số sử dụng và lợi ích chung của lập trình phía máy chủ được liệt kê bên dưới. Bạn sẽ lưu ý rằng có một số chồng chéo!</p>
+
+<h3 id="Lưu_trữ_và_cung_cấp_thông_tin_hiệu_quả">Lưu trữ và cung cấp thông tin hiệu quả</h3>
+
+<p>Hãy tưởng tượng có bao nhiêu sản phẩm có sẵn trên Amazon và tưởng tượng có bao nhiêu bài viết đã được viết trên Facebook? Tạo một trang tĩnh riêng cho từng sản phẩm hoặc bài đăng sẽ hoàn toàn không thực tế.</p>
+
+<p>Thay vào đó, lập trình phía máy chủ cho phép chúng tôi lưu trữ thông tin trong cơ sở dữ liệu và tự động xây dựng và trả về HTML và các loại tệp khác (ví dụ: PDF, hình ảnh, v.v.). Cũng có thể chỉ cần trả lại dữ liệu ({{glossary("JSON")}}, {{glossary("XML")}}, v.v) để hiển thị bằng các khung web phía máy khách thích hợp (điều này giúp giảm gánh nặng xử lý trên máy chủ và lượng dữ liệu cần gửi).</p>
+
+<p>Máy chủ không giới hạn gửi thông tin từ cơ sở dữ liệu và có thể trả về kết quả của các công cụ phần mềm hoặc dữ liệu từ các dịch vụ truyền thông. Nội dung thậm chí có thể được nhắm mục tiêu cho loại thiết bị khách đang nhận nó.</p>
+
+<p>Vì thông tin có trong cơ sở dữ liệu, nên nó cũng có thể dễ dàng chia sẻ và cập nhật hơn với các hệ thống kinh doanh khác (ví dụ: khi sản phẩm được bán trực tuyến hoặc trong cửa hàng, cửa hàng có thể cập nhật cơ sở dữ liệu về hàng tồn kho).</p>
+
+<div class="note">
+<p><strong>Note</strong>: Trí tưởng tượng của bạn không nhất thiết phải làm việc chăm chỉ để xem lợi ích của mã server-side cho việc lưu trữ và cung cấp thông tin hiệu quả:</p>
+
+<ol>
+ <li>Truy cập <a href="https://www.amazon.com/">Amazon</a> hoặc một số trang web thương mại điện tử khác.</li>
+ <li>Tìm kiếm một số từ khóa và lưu ý cách thức cấu trúc trang không thay đổi, mặc dù kết quả thực hiện.</li>
+ <li>Mở hai hoặc ba sản phẩm khác nhau. Lưu ý một lần nữa cách chúng có cấu trúc và bố cục chung, nhưng nội dung cho các sản phẩm khác nhau đã được lấy từ cơ sở dữ liệu.</li>
+</ol>
+
+<p>Đối với cụm từ tìm kiếm chung (giả sử "cá" ), bạn có thể thấy hàng triệu giá trị được trả về theo nghĩa đen. Sử dụng cơ sở dữ liệu cho phép những thứ này được lưu trữ và chia sẻ hiệu quả, và nó cho phép việc trình bày thông tin được kiểm soát chỉ ở một nơi.</p>
+</div>
+
+<h3 id="Tùy_chỉnh_trải_nghiệm_người_dùng">Tùy chỉnh trải nghiệm người dùng</h3>
+
+<p>Máy chủ có thể lưu trữ và sử dụng thông tin về khách hàng để cung cấp trải nghiệm người dùng thuận tiện và phù hợp. Ví dụ: nhiều trang web lưu trữ thẻ tín dụng để các chi tiết không phải nhập lại. Các trang web như Google Maps có thể sử dụng các vị trí đã lưu hoặc hiện tại để cung cấp thông tin định tuyến và lịch sử tìm kiếm hoặc du lịch để làm nổi bật các doanh nghiệp địa phương trong kết quả tìm kiếm.</p>
+
+<p>Một phân tích sâu hơn về thói quen người dùng có thể được sử dụng để dự đoán sở thích của họ và tùy chỉnh thêm các phản hồi và thông báo, ví dụ như cung cấp danh sách các địa điểm phổ biến đã truy cập trước đây hoặc bạn có thể muốn xem trên bản đồ.</p>
+
+<div class="note">
+<p><strong>Note: </strong><a href="https://maps.google.com/">Google Maps</a> lưu lịch sử tìm kiếm và truy cập của bạn. Các địa điểm thường xuyên truy cập hoặc tìm kiếm thường được tô sáng hơn các địa điểm khác.</p>
+
+<p>Kết quả tìm kiếm của Google được tối ưu hóa dựa trên các tìm kiếm trước đó.</p>
+
+<ol>
+ <li> Chuyển đến tìm kiếm <a href="https://google.com/">Google</a>.</li>
+ <li> Tìm kiếm "bóng đá".</li>
+ <li>Bây giờ hãy thử gõ "yêu thích" vào hộp tìm kiếm và quan sát các dự đoán tìm kiếm tự động hoàn tất.</li>
+</ol>
+
+<p>Sự trùng hợp? Không có gì!</p>
+</div>
+
+<h3 id="Kiểm_soát_truy_cập_nội_dung">Kiểm soát truy cập nội dung</h3>
+
+<p>Lập trình phía máy chủ cho phép các trang web hạn chế quyền truy cập đối với người dùng được ủy quyền và chỉ cung cấp thông tin mà người dùng được phép xem.</p>
+
+<p>Các ví dụ trong thế giới thực bao gồm:</p>
+
+<ul>
+ <li>Các mạng xã hội như Facebook cho phép người dùng kiểm soát hoàn toàn dữ liệu của riêng họ nhưng chỉ cho phép bạn bè của họ xem hoặc nhận xét về nó. Người dùng xác định ai có thể xem dữ liệu của họ và bằng tiện ích mở rộng, dữ liệu của ai xuất hiện trong nguồn cấp dữ liệu của họ - ủy quyền là một phần trung tâm của trải nghiệm người dùng!</li>
+ <li>
+ <p>Trang web bạn đang truy cập ngay bây giờ kiểm soát quyền truy cập vào nội dung: mọi người đều có thể xem bài viết, nhưng chỉ những người dùng đã đăng nhập mới có thể chỉnh sửa chúng. Để thử điều này, nhấp vào nút <strong>Chỉnh sửa (Edit)</strong> ở đầu trang này - nếu bạn đã đăng nhập, bạn sẽ được hiển thị chế độ xem chỉnh sửa; nếu bạn chưa đăng nhập, bạn sẽ được đưa đến trang đăng ký.</p>
+ </li>
+</ul>
+
+<div class="note">
+<p><strong>Note</strong>: Xem xét các ví dụ thực tế khác, nơi quyền truy cập vào nội dung được kiểm soát. Ví dụ: bạn có thể thấy gì nếu bạn truy cập trang web trực tuyến cho ngân hàng của mình? Đăng nhập vào tài khoản của bạn - bạn có thể xem và sửa đổi thông tin bổ sung nào? Thông tin nào bạn có thể thấy rằng chỉ có ngân hàng mới có thể thay đổi?</p>
+</div>
+
+<h3 id="Lưu_trữ_thông_tin_phiên_trạng_thái">Lưu trữ thông tin phiên / trạng thái</h3>
+
+<p>Lập trình phía máy chủ cho phép các nhà phát triển sử dụng các <strong>phiên</strong> - về cơ bản, một cơ chế cho phép máy chủ lưu trữ thông tin về người dùng hiện tại của trang web và gửi các phản hồi khác nhau dựa trên thông tin đó.</p>
+
+<p>Ví dụ, điều này cho phép một trang web biết rằng người dùng đã đăng nhập trước đó và hiển thị các liên kết đến email hoặc lịch sử đặt hàng của họ hoặc có thể lưu trạng thái của một trò chơi đơn giản để người dùng có thể truy cập lại trang web và tiếp tục họ đã bỏ nó</p>
+
+<div class="note">
+<p><strong>Note</strong>: Truy cập trang web báo có mô hình đăng ký và mở một loạt các tab (ví dụ: <a href="http://www.theage.com.au/">The Age</a>). Tiếp tục truy cập trang web trong một vài giờ / ngày. Cuối cùng, bạn sẽ bắt đầu được chuyển hướng đến các trang giải thích cách đăng ký và bạn sẽ không thể truy cập các bài viết. Thông tin này là một ví dụ về thông tin phiên được lưu trữ trong cookie.</p>
+</div>
+
+<h3 id="Thông_báo_và_liên_lạc">Thông báo và liên lạc</h3>
+
+<p>Máy chủ có thể gửi thông báo chung hoặc cụ thể cho người dùng thông qua trang web hoặc qua email, SMS, tin nhắn tức thời, cuộc trò chuyện video hoặc các dịch vụ liên lạc khác.</p>
+
+<p>Một vài ví dụ bao gồm:</p>
+
+<ul>
+ <li>Facebook và Twitter gửi email và tin nhắn SMS để thông báo cho bạn về các liên lạc mới.</li>
+ <li>Amazon thường xuyên gửi e-mail sản phẩm đề xuất các sản phẩm tương tự như những sản phẩm đã mua hoặc đã xem mà bạn có thể quan tâm.</li>
+ <li>Một máy chủ web có thể gửi thông điệp cảnh báo đến quản trị viên trang web cảnh báo chúng về bộ nhớ thấp trên máy chủ hoặc hoạt động đáng ngờ của người dùng.</li>
+</ul>
+
+<div class="note">
+<p><strong>Note</strong>: Loại thông báo phổ biến nhất là "xác nhận đăng ký". Chọn hầu hết mọi trang web lớn mà bạn quan tâm (Google, Amazon, Instagram, v.v.) và tạo một tài khoản mới bằng địa chỉ email của bạn. Bạn sẽ sớm nhận được một email xác nhận đăng ký của bạn hoặc yêu cầu xác nhận để kích hoạt tài khoản của bạn.</p>
+</div>
+
+<h3 id="Phân_tích_dữ_liệu">Phân tích dữ liệu</h3>
+
+<p>Một trang web có thể thu thập rất nhiều dữ liệu về người dùng: những gì họ tìm kiếm, những gì họ mua, những gì họ giới thiệu, thời gian họ ở lại trên mỗi trang. Lập trình phía máy chủ có thể được sử dụng để tinh chỉnh các phản hồi dựa trên phân tích dữ liệu này.</p>
+
+<p>Ví dụ: Amazon và Google đều quảng cáo sản phẩm dựa trên các tìm kiếm trước đó (và mua hàng).</p>
+
+<div class="note">
+<p><strong>Note</strong>: Nếu bạn là người dùng Facebook, hãy truy cập nguồn cấp dữ liệu chính của bạn và xem luồng bài đăng. Lưu ý cách một số bài đăng không theo thứ tự số - cụ thể, các bài đăng có nhiều lượt "thích" thường cao hơn trong danh sách so với các bài đăng gần đây.</p>
+
+<p>Ngoài ra, hãy nhìn vào loại quảng cáo bạn đang được hiển thị - bạn có thể thấy quảng cáo cho những thứ bạn đã xem trên các trang web khác. Thuật toán của Facebook để làm nổi bật nội dung và quảng cáo có thể là một bí ẩn, nhưng rõ ràng là nó phụ thuộc vào sở thích và thói quen xem của bạn!</p>
+</div>
+
+<h2 id="Tóm_lược">Tóm lược</h2>
+
+<p>Xin chúc mừng, bạn đã đến cuối bài viết đầu tiên về lập trình phía máy chủ. </p>
+
+<p>Bây giờ bạn đã biết rằng mã phía máy chủ được chạy trên máy chủ web và vai trò chính của nó là kiểm soát <em>thông tin</em> nào được gửi đến người dùng (trong khi mã phía máy khách chủ yếu xử lý cấu trúc và trình bày dữ liệu đó cho người dùng) </p>
+
+<p>Bạn cũng nên hiểu rằng nó hữu ích vì nó cho phép chúng tôi tạo các trang web cung cấp thông tin phù hợp cho người dùng cá nhân và có ý tưởng tốt về một số điều bạn có thể làm khi bạn là lập trình viên phía máy chủ.</p>
+
+<p>Cuối cùng, bạn nên hiểu rằng mã phía máy chủ có thể được viết bằng một số ngôn ngữ lập trình và bạn nên sử dụng web framework để làm cho toàn bộ quá trình dễ dàng hơn.</p>
+
+<p>Trong một bài viết trong tương lai, chúng tôi sẽ giúp bạn chọn web framework tốt nhất cho trang web đầu tiên của bạn. Ở đây chúng tôi sẽ đưa bạn qua các tương tác máy khách-máy chủ chính chỉ chi tiết hơn một chút.</p>
+
+<p>{{NextMenu("Learn/Server-side/First_steps/Client-Server_overview", "Learn/Server-side/First_steps")}}</p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Server-side/First_steps/Introduction">Introduction to the server side</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview">Client-Server overview</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/First_steps/Web_frameworks">Server-side web frameworks</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/First_steps/Website_security">Website security</a></li>
+</ul>
diff --git a/files/vi/learn/server-side/index.html b/files/vi/learn/server-side/index.html
new file mode 100644
index 0000000000..e2c651cc55
--- /dev/null
+++ b/files/vi/learn/server-side/index.html
@@ -0,0 +1,59 @@
+---
+title: Lập trình website khía cạnh server
+slug: Learn/Server-side
+tags:
+ - Beginner
+ - CodingScripting
+ - Intro
+ - Landing
+ - Learn
+ - NeedsTranslation
+ - Server
+ - Server-side programming
+ - Topic
+ - TopicStub
+translation_of: Learn/Server-side
+---
+<div>{{LearnSidebar}}</div>
+
+<p class="summary">Chủ đề <strong>Web động - Lập trình phía máy chủ </strong>là một loạt các bài viết hướng dẫn cách tạo ra các trang web động; là các trang web sẽ cung cấp thông tin tùy chỉnh dựa trên một yêu cầu HTTP. Các bài viết sẽ cung cấp một sự giới thiệu chung cho lập trình phía máy chủ, đi kèm với hướng dẫn cụ thể cho người mới bắt đầu trên các framework như Django (Python) và Express (Node.js/Javascript) để tạo nên các ứng dụng cơ bản.</p>
+
+<p>Các trang web phổ biến nhất sử dụng một số kỹ thuật về phía máy chủ để hiển thị dữ liệu động khác nhau khi được yêu cầu. Ví dụ, hình dung rằng có bao nhiêu sản phẩm bày bán trên Amazon, và hình dung rằng có bao nhiêu bài đăng được viết trên Facebook? Việc hiển thị tất cả những nội dung đó trên các trang tĩnh là hoàn toàn không hiệu quả, do đó thay vì các trang hiển thị tĩnh (xây dựng dựa trên HTML, CSS và Javascript), thì tự động cập nhật dữ liệu được hiển thị bên trong các trang đó khi cần, ví dụ: khi bạn muốn xem một sản phẩm khác trên Amazon. </p>
+
+<p>Trong thế giới phát trển web hiện đại, việc học về phát triển phía máy chủ rất được khuyến khích.</p>
+
+<h2 id="Chặng_đường_học_tập">Chặng đường học tập</h2>
+
+<p>Bắt đầu với lập trình phía máy chủ thường dễ hơn so với phát triển phía máy khách, vì các trang web động có xu hướng thực hiện rất nhiều hoạt động tương tự nhau( lấy dữ liệu từ cơ sở dữ liệu và hiển thị nó trong một trang, xác thực dữ liệu do người dùng nhập và lưu nó trong cơ sở dữ liệu, kiểm tra quyền người dùng và ghi nhật ký người dùng, v.v.) và được xây dựng bằng cách sử dụng web framework làm cho các thao tác trên máy chủ web trở nên dễ dàng hơn.</p>
+
+<p>Một kiến ​​thức cơ bản về các khái niệm lập trình (hoặc của một ngôn ngữ lập trình cụ thể) là hữu ích, nhưng không cần thiết. Tương tự như vậy, chuyên môn về lập trình phía máy khách là không cần thiết, nhưng kiến ​​thức cơ bản sẽ giúp bạn làm việc tốt hơn với các nhà phát triển tạo trang web phía máy khách của bạn.</p>
+
+<p>Bạn sẽ cần phải hiểu "web làm việc thế nào". Chúng tôi giới thiệu bạn một số chủ đề cơ bản:</p>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Common_questions/What_is_a_web_server">What is a web server</a></li>
+ <li><a href="/en-US/docs/Learn/Common_questions/What_software_do_I_need">What software do I need to build a website?</a></li>
+ <li><a href="/en-US/docs/Learn/Common_questions/Upload_files_to_a_web_server">How do you upload files to a web server?</a></li>
+</ul>
+
+<p>Với sự hiểu biết cơ bản, bạn sẽ sẵn sàng để qua phần Modules trong bài viết này. </p>
+
+<h2 id="Modules">Modules</h2>
+
+<p>Chủ đề này chứa một số module. Bạn nên bắt đầu với module đầu tiên, sau đó đến 1 trong 2 module sau, đây là 2 ngôn ngữ server side rất phổ biến sẽ cho bạn thấy cách nó hoạt động</p>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/Server-side/First_steps">Server-side website programming first steps</a></dt>
+ <dd>This module provides server-technology-agnostic information about server-side website programming, including answers to fundamental questions about server-side programming — "what it is", "how it differs from client-side programming", and "why it is so useful" — and an overview of some of the more popular server-side web frameworks and guidance on how to select the most suitable for your site. Lastly we provide an introductory section on web server security.</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Django">Django Web Framework (Python)</a></dt>
+ <dd>Django is an extremely popular and fully featured server-side web framework, written in Python. The module explains why Django is such a good web server framework, how to set up a development environment and how to perform common tasks with it.</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs">Express Web Framework (Node.js/JavaScript)</a></dt>
+ <dd>Express is a popular web framework, written in JavaScript and hosted within the node.js runtime environment. The module explains some of the key benefits of this framework, how to set up your development environment and how to perform common web development and deployment tasks.</dd>
+</dl>
+
+<h2 id="Xem_thêm">Xem thêm</h2>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/Server-side/Node_server_without_framework">Node server without framework</a></dt>
+ <dd>This article provides a simple static file server built with pure Node.js, for those of you not wanting to use a framework.</dd>
+</dl>