Skip to content

Commit 2f12523

Browse files
authoredJun 24, 2020
Merge pull request #2 from coderoad/update/crc-v0.4.1
update readme to #.# format
2 parents 5400e51 + be9d582 commit 2f12523

File tree

2 files changed

+102
-102
lines changed

2 files changed

+102
-102
lines changed
 

‎TUTORIAL.md

+29-29
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Build a server with Node & Express
44

5-
## L1 Meet the Node Console
5+
## 1. Meet the Node Console
66

77
> Introduction to the Node console
88
@@ -18,7 +18,7 @@ During the development process, it is important to be able to check what’s goi
1818

1919
We recommend to keep the log panel open while working at these challenges. By reading the logs, you can be aware of the nature of errors that may occur.
2020

21-
### L1S1
21+
### 1.1
2222

2323
NPM install the "express" library module version. Use version 4.x.
2424

@@ -28,11 +28,11 @@ NPM install the "express" library module version. Use version 4.x.
2828
* Run `npm install <package>`
2929
* Run `npm install express`
3030

31-
### L1S2
31+
### 1.2
3232

3333
Modify the `server.js` file to log "Hello World" to the console.
3434

35-
## L2 Start a Working Server
35+
## 1. Start a Working Server
3636

3737
> Create a server
3838
@@ -50,13 +50,13 @@ function(req, res) {
5050

5151
will serve the string 'Response String'.
5252

53-
### L2S1
53+
### 2.1
5454

5555
Use the `app.get()` method to serve the string "Hello Express" to GET requests matching the `/` (root) path.
5656

5757
**Note:** Be sure that your code works by looking at the logs, then see the results in your browser by running `npm start`.
5858

59-
## L3 Serve an HTML File
59+
## 3. Serve an HTML File
6060

6161
> Serve an HTML file over the server
6262
@@ -66,61 +66,61 @@ You can respond to requests with a file using the `res.sendFile(path)` method. Y
6666
absolutePath = __dirname + relativePath / file.ext;
6767
```
6868

69-
### L3S1
69+
### 3.1
7070

7171
Send the `/views/index.html` file as a response to GET requests to the `/` path. If you view your live app, you should see a big HTML heading (and a form that we will use later…), with no style applied.
7272

7373
**Note:** You can edit the solution of the previous challenge or create a new one. If you create a new solution, keep in mind that Express evaluates routes from top to bottom, and executes the handler for the first match. You have to comment out the preceding solution, or the server will keep responding with a string.
7474

75-
## L4 Serve Static Assets
75+
## 4. Serve Static Assets
7676

7777
> Serve static CSS
7878
7979
An HTML server usually has one or more directories that are accessible by the user. You can place there the static assets needed by your application (stylesheets, scripts, images). In Express, you can put in place this functionality using the middleware `express.static(path)`, where the `path` parameter is the absolute path of the folder containing the assets. If you don’t know what middleware is... don’t worry, we will discuss in detail later. Basically, middleware are functions that intercept route handlers, adding some kind of information. A middleware needs to be mounted using the method `app.use(path, middlewareFunction)`. The first `path` argument is optional. If you don’t pass it, the middleware will be executed for all requests.
8080

81-
### L4S1
81+
### 4.1
8282

8383
Mount the `express.static()` middleware for all requests with `app.use()`. The absolute path to the assets folder is `\_\_dirname + /public`.
8484
Now your app should be able to serve a CSS stylesheet. From outside, the public folder will appear mounted to the root directory. Your front-page should look a little better now!
8585

86-
## L5 Serve JSON on a Route
86+
## 5. Serve JSON on a Route
8787

8888
> Serve JSON over a REST API
8989
9090
While an HTML server serves (you guessed it!) HTML, an API serves data. A <dfn>REST</dfn> (REpresentational State Transfer) API allows data exchange in a simple way, without the need for clients to know any detail about the server. The client only needs to know where the resource is (the URL), and the action it wants to perform on it (the verb). The GET verb is used when you are fetching some information, without modifying anything. These days, the preferred data format for moving information around the web is JSON. Simply put, JSON is a convenient way to represent a JavaScript object as a string, so it can be easily transmitted.
9191

9292
Let's create a simple API by creating a route that responds with JSON at the path `/json`. You can do it as usual, with the `app.get()` method. Inside the route handler, use the method `res.json()`, passing in an object as an argument. This method closes the request-response loop, returning the data. Behind the scenes, it converts a valid JavaScript object into a string, then sets the appropriate headers to tell your browser that you are serving JSON, and sends the data back. A valid object has the usual structure `{key: data}`. `data` can be a number, a string, a nested object or an array. `data` can also be a variable or the result of a function call, in which case it will be evaluated before being converted into a string.
9393

94-
### L5S1
94+
### 5.1
9595

9696
Serve the object `{"message": "Hello json"}` as a response, in JSON format, to GET requests to the `/json` route. Then point your browser to `your-app-url/json`, you should see the message on the screen.
9797

98-
## L6 Use the .env File
98+
## 6. Use the .env File
9999

100100
> Load secrets with the .env file
101101
102102
The `.env` file is a hidden file that is used to pass environment variables to your application. This file is secret, no one but you can access it, and it can be used to store data that you want to keep private or hidden. For example, you can store API keys from external services or your database URI. You can also use it to store configuration options. By setting configuration options, you can change the behavior of your application, without the need to rewrite some code.
103103

104104
The environment variables are accessible from the app as `process.env.VAR_NAME`. The `process.env` object is a global Node object, and variables are passed as strings. By convention, the variable names are all uppercase, with words separated by an underscore. The `.env` is a shell file, so you don’t need to wrap names or values in quotes. It is also important to note that there cannot be space around the equals sign when you are assigning values to your variables, e.g. `VAR_NAME=value`. Usually, you will put each variable definition on a separate line.
105105

106-
### L6S1
106+
### 6.1
107107

108108
Create a .env file in the root of your project.
109109

110-
### L6S2
110+
### 6.2
111111

112112
Add the .env file to your .gitignore file. It should be kept a secret.
113113

114-
### L6S3
114+
### 6.3
115115

116116
Let's add an environment variable as a configuration option.
117117
Store the variable `MESSAGE_STYLE=uppercase` in the `.env` file.
118118

119-
### L6S4
119+
### 6.4
120120

121121
Install the dependency for the package "dotenv" as a devDependency (`npm install --save-dev module`). The package helps make variables from the .env file available in your code.
122122

123-
### L6S5
123+
### 6.5
124124

125125
Load dependencies into your server.js by adding the following line to the top of your file:
126126

@@ -130,11 +130,11 @@ require("dotenv").config();
130130

131131
You can test if it works by logging `process.env.MESSAGE_STYLE`.
132132

133-
### L6S6
133+
### 6.6
134134

135135
Tell the GET `/json` route handler that you created in the last challenge to transform the response object’s message to uppercase if `process.env.MESSAGE_STYLE` equals `uppercase`. The response object should become `{"message": "HELLO JSON"}`.
136136

137-
## L7 Root-Level Request Logger Middleware
137+
## 7. Root-Level Request Logger Middleware
138138

139139
> Add logger middleware
140140
@@ -153,13 +153,13 @@ Let’s suppose you mounted this function on a route. When a request matches the
153153

154154
In this exercise, you are going to build root-level middleware. As you have seen in challenge 4, to mount a middleware function at root level, you can use the `app.use(&lt;mware-function&gt;)` method. In this case, the function will be executed for all the requests, but you can also set more specific conditions. For example, if you want a function to be executed only for POST requests, you could use `app.post(&lt;mware-function&gt;)`. Analogous methods exist for all the HTTP verbs (GET, DELETE, PUT, …).
155155

156-
### L7S1
156+
### 7.1
157157

158158
Build a simple logger. For every request, it should log to the console a string taking the following format: `method path - ip`. An example would look like this: `GET /json - ::ffff:127.0.0.1`. Note that there is a space between `method` and `path` and that the dash separating `path` and `ip` is surrounded by a space on both sides. You can get the request method (http verb), the relative route path, and the caller’s ip from the request object using `req.method`, `req.path` and `req.ip`. Remember to call `next()` when you are done, or your server will be stuck forever. Be sure to have the ‘Logs’ opened, and see what happens when some request arrives.
159159

160160
**Note:** Express evaluates functions in the order they appear in the code. This is true for middleware too. If you want it to work for all the routes, it should be mounted before them.
161161

162-
## L8 Chain Middleware
162+
## 8. Chain Middleware
163163

164164
> Combine middleware in a chain
165165
@@ -181,38 +181,38 @@ app.get(
181181

182182
This approach is useful to split the server operations into smaller units. That leads to a better app structure, and the possibility to reuse code in different places. This approach can also be used to perform some validation on the data. At each point of the middleware stack you can block the execution of the current chain and pass control to functions specifically designed to handle errors. Or you can pass control to the next matching route, to handle special cases. We will see how in the advanced Express section.
183183

184-
### L8S1
184+
### 8.1
185185

186186
In the route `app.get('/now', ...)` chain a middleware function and the final handler. In the middleware function you should add the current time to the request object in the `req.time` key. You can use `new Date().toString()`. In the handler, respond with a JSON object, taking the structure `{time: req.time}`.
187187
**Note:** The test will not pass if you don’t chain the middleware. If you mount the function somewhere else, the test will fail, even if the output result is correct.
188188

189-
## L9 Route Parameter Input
189+
## 9. Route Parameter Input
190190

191191
> Pass params in route names
192192
193193
When building an API, we have to allow users to communicate to us what they want to get from our service. For example, if the client is requesting information about a user stored in the database, they need a way to let us know which user they're interested in. One possible way to achieve this result is by using route parameters. Route parameters are named segments of the URL, delimited by slashes (/). Each segment captures the value of the part of the URL which matches its position. The captured values can be found in the `req.params` object.
194194

195195
<blockquote>route_path: '/user/:userId/book/:bookId'<br>actual_request_URL: '/user/546/book/6754' <br>req.params: {userId: '546', bookId: '6754'}</blockquote>
196196

197-
### L9S1
197+
### 9.1
198198

199199
Build an echo server, mounted at the route `GET /echo/:word`. Respond with a JSON object, taking the structure `{echo: word}`. You can find the word to be repeated at `req.params.word`.
200200

201-
## L10 Query Parameter Input
201+
## 10. Query Parameter Input
202202

203203
> Pass params in a query string
204204
205205
Another common way to get input from the client is by encoding the data after the route path, using a query string. The query string is delimited by a question mark (?), and includes field=value couples. Each couple is separated by an ampersand (&). Express can parse the data from the query string, and populate the object `req.query`. Some characters, like the percent (%), cannot be in URLs and have to be encoded in a different format before you can send them. If you use the API from JavaScript, you can use specific methods to encode/decode these characters.
206206

207207
<blockquote>route_path: '/library'<br>actual_request_URL: '/library?userId=546&bookId=6754' <br>req.query: {userId: '546', bookId: '6754'}</blockquote>
208208

209-
### L10S1
209+
### 10.1
210210

211211
Build an API endpoint, mounted at `GET /name`. Respond with a JSON document, taking the structure `{ name: 'firstname lastname'}`. The first and last name parameters should be encoded in a query string e.g. `?first=firstname&last=lastname`.
212212

213213
**Note:** In the following exercise you are going to receive data from a POST request, at the same `/name` route path. If you want, you can use the method `app.route(path).get(handler).post(handler)`. This syntax allows you to chain different verb handlers on the same path route. You can save a bit of typing, and have cleaner code.
214214

215-
## L11 Body-Parser
215+
## 11. Body-Parser
216216

217217
> Parse JSON from POST requests
218218
@@ -231,11 +231,11 @@ name=John+Doe&age=25
231231
As you can see, the body is encoded like the query string. This is the default format used by HTML forms. With Ajax, you can also use JSON to handle data having a more complex structure. There is also another type of encoding: multipart/form-data. This one is used to upload binary files.
232232
In this exercise, you will use a urlencoded body. To parse the data coming from POST requests, you have to install the `body-parser` package. This package allows you to use a series of middleware, which can decode data in different formats.
233233

234-
### L11S1
234+
### 11.1
235235

236236
Install the `body-parser` module in your `package.json`.
237237

238-
### L11S2
238+
### 11.2
239239

240240
Require "body-parser" at the top of the server.js file. Store it in a variable named `bodyParser`. The middleware to handle urlencoded data is returned by `bodyParser.urlencoded({extended: false})`. Pass to `app.use()` the function returned by the previous method call. As usual, the middleware must be mounted before all the routes which need it.
241241

0 commit comments

Comments
 (0)