小程序 timestamp

by Ayo Isaiah

通过Ayo Isaiah

通过构建Timestamp微服务应用程序来学习Node.js (Learn Node.js by building a Timestamp Microservice app)

One of the reasons why Node.js is such a great platform for building applications is the abundance of libraries that have been developed by the community for practically all the common use cases. This makes it really easy to go from idea to a production-ready application in a relatively short space of time.

Node.js之所以成为构建应用程序如此出色的平台的原因之一,是社区为几乎所有常见用例开发的大量库。 这使得在相对短的时间内从构思转变为生产就绪的应用程序变得非常容易。

That said, at least understanding Node.js’s standard libraries will always be beneficial to you, especially if you want to gain a deeper understanding of how Node.js works.

也就是说,至少了解Node.js的标准库将始终对您有益,特别是如果您想更深入地了解Node.js的工作原理时。

In this article, you’ll learn how to build a timestamp microservice using a few built-in Node.js modules. Here’s a live demo of what we’ll be building. You can find the complete source code for this project in this GitHub repo.

在本文中,您将学习如何使用一些内置的Node.js模块构建时间戳微服务 。 这是我们将要构建的实时演示 。 您可以在此GitHub存储库中找到该项目的完整源代码。

先决条件 (Prerequisites)

You need to have previous experience with building JavaScript applications in the browser, but no prior experience with Node.js is required. Before you continue though, you need to have Node.js and npm installed.

您需要具有在浏览器中构建JavaScript应用程序的先前经验,但是不需要具有Node.js的先前经验。 但是,在继续之前,您需要安装Node.js和npm

You can visit the Node.js website to view installation instructions for your operating system. npm comes bundled with Node, so once you install Node, you’ll have access to the npm command too.

您可以访问Node.js网站以查看操作系统的安装说明。 npm与Node捆绑在一起,因此,一旦安装Node,您就可以访问npm命令。

The versions I used while building this project are as follows:

构建该项目时使用的版本如下:

  • Node.js v10.9.0Node.js v10.9.0
  • npm v6.4.1npm v6.4.1

You can view the version of Node and npm you have installed by running the following commands in your terminal:

您可以通过在终端中运行以下命令来查看已安装的Node和npm的版本:

node -vnpm -v

用户故事 (User stories)

Here are the user stories for this project:

以下是此项目的用户案例:

  1. The API endpoint is GET [project_url]/api/timestamp/:date_string?

    API端点是GET [project_url]/api/timestamp/:date_string?

  2. A date string is valid if it can be successfully parsed by new Date(date_string). Note that the unix timestamp needs to be an integer (not a string) specifying milliseconds. In our test we will use date strings compliant with ISO-8601 (e.g. “2016-11-20”) because this will ensure an UTC timestamp.

    如果可以通过new Date(date_string)成功解析日期字符串,则该日期字符串有效。 请注意,Unix时间戳记必须为整数(不是字符串),以毫秒为单位。 在我们的测试中,我们将使用符合ISO-8601的日期字符串(例如“ 2016-11-20”),因为这将确保UTC时间戳。

  3. If the date string is empty, it should be equivalent to trigger new Date(), i.e. the service uses the current timestamp.

    如果日期字符串为空,则它应等效于触发new Date() ,即服务使用当前时间戳。

  4. If the date string is valid, the API returns a JSON having the structure {"unix": <date.getTime()>, "utc" : <date.toUTCString()> } e.g. {"unix": 1479663089000 ,"utc": "Sun, 20 Nov 2016 17:31:29 GMT"}.

    如果日期字符串有效,则API返回具有以下结构的JSON {"unix": <date.getTime()>, "utc" : <date.toUTCSt ring() > } eg {"unix": 1479663089000 ,"utc": "Sun, 20 Nov 2016 17 GMT”}。

  5. If the date string is invalid, the API returns a JSON having the structure {"error" : "Invalid Date" }.

    如果日期字符串无效,则API返回结构为{"error" : "Invalid Date" }的JSON。

入门 (Getting started)

Open a new terminal instance on your computer, then create a new directory for this project in your filesystem, and change into it using the following commands:

在计算机上打开一个新的终端实例,然后在文件系统中为此项目创建一个新目录,并使用以下命令将其更改为:

mkdir timestamp-microservicecd timestamp-microservice

The first step when starting a new Node project is to initialize it with a package.json file. This file contains some information about a project including its name, description, author and all the packages that it depends on. Here’s the command that helps you create a package.json file for your project:

启动新的Node项目的第一步是使用package.json文件对其进行初始化。 该文件包含有关项目的一些信息,包括其名称,描述,作者及其依赖的所有软件包。 这是可以帮助您为项目创建package.json文件的命令:

npm init

Running the above command opens up a prompt that allows you to input the information for specific parts of your project in the following order:

运行上面的命令将打开一个提示,允许您按以下顺序输入项目特定部分的信息:

  1. The name of the project.项目的名称。
  2. The project’s initial version.项目的初始版本。
  3. The project description.项目说明。
  4. The project’s entry file.项目的入口文件。
  5. The project’s test command.项目的测试命令。
  6. The git repository for the project,该项目的git存储库,
  7. Keywords related to the project.与项目相关的关键字。
  8. The project license.项目许可证。

If you’re satisfied with the suggestion that the command provides next to each field (in brackets), just hit the Enter key to accept it and move on to the next field until the command exits. You can also use npm init -y to quickly populate a package.json file with all the default values.

如果您对命令在每个字段旁边(在方括号中)提供的建议感到满意,只需按Enter键以接受它,然后继续下一个字段,直到命令退出。 您还可以使用npm init -y快速使用所有默认值填充package.json文件。

The next step is to create an index.js file at the root of your project directory. This is where we will be writing the code for this project.

下一步是在项目目录的根目录下创建一个index.js文件。 这是我们将为该项目编写代码的地方。

touch index.js

Finally, create a views folder at the root of your project directory. This folder will contain two HTML files: index.html and 404.html.

最后,在项目目录的根目录下创建一个views文件夹。 该文件夹将包含两个HTML文件: index.html404.html

mkdir viewstouch views/index.html views/404.html

Open up the project folder in your favourite text editor. We can now start building the application.

在您喜欢的文本编辑器中打开项目文件夹。 现在,我们可以开始构建应用程序了。

创建一个HTTP Web服务器 (Create an HTTP web server)

Open up index.js and type the following code into it:

打开index.js并在其中输入以下代码:

const http = require("http");
const requestHandler = (req, res) => {  console.log(req.url);  res.end('Hello world!');};
const server = http.createServer(requestHandler);
server.listen(process.env.PORT || 4100, err => {  if (err) throw err;
console.log(`Server running on PORT ${server.address().port}`);});

The first line requires the http module that ships with Node and makes it accessible through the http variable. Then, we utilize the createServer method on the http module to create a new instance of an HTTP server which is then stored in the server variable.

第一行需要Node附带的http模块,并使其可以通过http变量访问。 然后,我们利用http模块上的createServer方法创建一个HTTP服务器的新实例,然后将其存储在server变量中。

Notice the requestHandler function created under the http variable. This function will be invoked on each incoming request to the web server. The req and res arguments are objects that represent the request from the client and server response respectively.

注意在http变量下创建的requestHandler函数。 将在对Web服务器的每个传入请求上调用此功能。 reqres参数是分别代表来自客户端和服务器响应的请求的对象。

The listen method starts the server and makes it listen for incoming connections on the PORT environmental variable (available on the process.env object) or 4100 if there’s nothing there. The callback function passed to the listen method will execute when the server starts. If the provided port is already taken, or the server cannot start for any other reason, an error is thrown. Otherwise, the console.log() statement is printed in the terminal.

listen方法启动服务器,并使其侦听PORT环境变量(在process.env对象上可用)或4100如果那里什么都没有)上的传入连接。 服务器启动时,将执行传递给listen方法的回调函数。 如果提供的端口已被占用,或者服务器由于任何其他原因而无法启动,则会引发错误。 否则, console.log()语句将显示在终端中。

You can start the server by running node index.js in the terminal. Once your server is running, visit http://localhost:4100 in your browser. You should see the words “Hello world!”.

您可以通过在终端中运行node index.js来启动服务器。 服务器运行后,在浏览器中访问http:// localhost:4100 。 您应该看到“ Hello world!”字样。

创建根路由 (Create the root route)

Since the http module is very basic, it doesn’t provide us with a router. So we have to manually check for the URL to decide what to do for each route. We want to provide instructions on how to use the timestamp microservice once the root route is hit just like in the demo.

由于http模块是非常基本的模块,因此它没有为我们提供路由器。 因此,我们必须手动检查URL,以决定对每个路由执行的操作。 我们希望提供有关如何在根路由被点击后如何使用时间戳微服务的说明,就像在演示中一样。

We can do this by modifying the requestHandler function like this:

我们可以通过修改requestHandler函数来做到这一点,如下所示:

const requestHandler = (req, res) => {  if (req.url === "/") {    // Do something  }};

A simple if statement can help us check if the incoming request url is exactly / and then we can put the logic for that route between the curly braces. In this case, we want to return some HTML explaining how the microservice works. Before you continue, copy and paste the following into the views/index.html file we created earlier and save the file.

一个简单的if语句可以帮助我们检查传入的请求url是否恰好是/ ,然后可以将该花括号之间的路由逻辑放入。 在这种情况下,我们想返回一些HTML来解释微服务的工作方式。 在继续之前,请将以下内容复制并粘贴到我们之前创建的views/index.html文件中,然后保存该文件。

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <meta name="viewport" content="width=device-width, initial-scale=1.0">  <meta http-equiv="X-UA-Compatible" content="ie=edge">  <title>Timestamp Microservice</title>  <style>    body {      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;      color: #333;        background-color: #f6f6f6;    }
.container {      width: 100%;      max-width: 800px;      margin-left: auto;      margin-right: auto;    }
li {      margin-bottom: 10px;    }
li, p {      font-size: 18px;    }
code {      font-size: 90%;    }
a {      color: #006fc6;    }  </style></head><body>  <div class="container">    <h1>API Project: Timestamp Microservice</h1>    <h3>User Stories:</h1>    <ol class="user-stories">      <li>The API endpoint is <code>GET [project_url]/api/timestamp/:date_string</code></li>      <li>A date string is valid if can be successfully parsed by <code>new Date(date_string)</code>.<br>        Note that the unix timestamp needs to be an <strong>integer</strong> (not a string) specifying <strong>milliseconds</strong>.<br>        In our test we will use date strings compliant with ISO-8601 (e.g. <code>"2016-11-20"</code>) because this will ensure an UTC timestamp.</li>      <li>If the date string is <strong>empty</strong> it should be equivalent to trigger <code>new Date()</code>, i.e. the service uses the current timestamp.</li>      <li>If the date string is <strong>valid</strong> the api returns a JSON having the structure<br><code>{"unix": <date.getTime()>, "utc" : <date.toUTCString()> }</code><br>        e.g. <code>{"unix": 1479663089000 ,"utc": "Sun, 20 Nov 2016 17:31:29 GMT"}</code></li>      <li>If the date string is <strong>invalid</strong> the api returns a JSON having the structure <br>        <code>{"error" : "Invalid Date" }</code>.      </li>    </ol>
<h3>Example Usage:</h3>    <ul>      <li>        <a href="api/timestamp/2015-12-25">[project url]/api/timestamp/2015-12-25</a>      </li>      <li>        <a href="api/timestamp/1450137600000">[project url]/api/timestamp/1450137600</a>      </li>    </ul>
<h3>Example Output:</h3>    <p>      <code>{"unix":1451001600000, "utc":"Fri, 25 Dec 2015 00:00:00 GMT"}</code>    </p>  </div></body></html>

So how do we send an HTML response to the browser? We can use the built-in fs module to read the file, and then send the file’s contents to the browser using the res argument which represents the server’s response.

那么我们如何将HTML响应发送到浏览器? 我们可以使用内置的fs模块读取文件,然后使用代表服务器响应的res参数将文件内容发送到浏览器。

Require the fs module just below the http one as shown below:

要求在http下方的fs模块如下所示:

const http = require("http");const fs = require("fs");

Then modify the requestHandler function to look like this:

然后修改requestHandler函数,使其看起来像这样:

const requestHandler = (req, res) => {  if (req.url === "/") {    fs.readFile("views/index.html", "utf8", (err, html) => {      if (err) throw err;
res.writeHead(200, { "Content-Type": "text/html" });      res.end(html);    });  }};

The readFile() method asynchronously reads the file provided in the first argument (views/index.html) using the provided encoding (utf8), and executes the provided callback function. If an error occurs while reading the file, an exception is thrown. Otherwise, the contents of the file becomes available in the second argument of the callback function (html) in this case.

readFile()方法使用提供的编码( utf8 )异步读取第一个参数( views/index.html )中提供的文件,并执行提供的回调函数。 如果读取文件时发生错误,则会引发异常。 否则,在这种情况下,文件的内容将在回调函数的第二个参数( html )中变为可用。

Now, we can send the contents of the html to the browser. But we need to set the HTTP response code as well as set a response header to tell the browser what the media type of the returned content actually is.

现在,我们可以将html的内容发送到浏览器。 但是我们需要设置HTTP响应代码以及设置响应标头,以告诉浏览器返回内容的媒体类型实际上是什么。

The writeHead() method on the server response object is used in this case. It accepts the status code as the first argument, and an object representing the response headers as the second. We’ve set the Content-Type header to text/html to ensures that the browser interprets the contents of our response as HTML.

在这种情况下,将使用服务器响应对象上的writeHead()方法。 它接受状态码作为第一个参数,并将代表响应头的对象作为第二个参数。 我们已经将Content-Type标头设置为text/html以确保浏览器将我们的响应内容解释为HTML。

Next, the end() method sends the contents of the index.html file to the browser in the response body and signals the end of the server response.

接下来, end()方法将index.html文件的内容发送到响应主体中的浏览器,并发出服务器响应结束的信号。

To try out the new additions to the code, you need to stop the server with Ctrl-C and start it again using node server.js, then refresh your browser. You should see the html from the views/index.html file on the page.

要尝试对代码进行新添加,您需要使用Ctrl-C停止服务器,然后使用node server.js重新启动它,然后刷新浏览器。 您应该在页面上的views/index.html文件中看到html。

将Nodemon设置为自动重启Node进程 (Set up Nodemon to auto restart Node process)

By default, you have to kill the server process and restart it whenever you make a change to your code, but there’s an easy way around that.

默认情况下,每当对代码进行更改时,您都必须终止服务器进程并重新启动它,但是有一种简单的方法可以解决此问题。

You need to install a tool called Nodemon which auto restarts the node process whenever your code changes. You can install this tool globally on your machine with npm:

您需要安装一个名为Nodemon的工具,该工具会在代码更改时自动重新启动节点进程。 您可以使用npm在您的计算机上全局安装此工具:

npm install -g nodemon

Once Nodemon is installed, kill the server process and start it again with nodemon index.js. Now the web server will be auto restarted whenever you make a change in your code. Pretty neat huh?

安装Nodemon后,请终止服务器进程,然后使用nodemon index.js重新启动它。 现在,只要更改代码,Web服务器就会自动重新启动。 相当整洁吧?

The next step is to set up a route for the timestamp microservice. According to user story #1, this service should be available under /api/timestamp/:date_string? where :date_string? represents the date string that will be passed to the service.

下一步是为时间戳微服务设置路由。 根据用户故事1,此服务应该在/api/timestamp/:date_string?下可用/api/timestamp/:date_string? 哪里:date_string? 表示将传递给服务的日期字符串。

Modify your index.js file so that it look likes this:

修改index.js文件,使其看起来像这样:

// require statements
const getTimestamp = date => ({  unix: date.getTime(),  utc: date.toUTCString()});
const requestHandler = (req, res) => {  if (req.url === "/") {    fs.readFile("views/index.html", (err, html) => {      if (err) throw err;
res.writeHead(200, { "Content-Type": "text/html" });      res.end(html);    });  } else if (req.url.startsWith("/api/timestamp")) {    const dateString = req.url.split("/api/timestamp/")[1];    let timestamp;
if (dateString === undefined || dateString.trim() === "") {      timestamp = getTimestamp(new Date());    } else {      const date = !isNaN(dateString)        ? new Date(parseInt(dateString))        : new Date(dateString);
if (!isNaN(date.getTime())) {        timestamp = getTimestamp(date);      } else {        timestamp = {          error: "invalid date"        };      }    }
res.writeHead(200, { "Content-Type": "application/json" });    res.end(JSON.stringify(timestamp));  }};
// rest of the file

I know that’s a lot of code to process so let me walk you through it bit by bit. We have an else if statement in requestHandler that checks if the request URL starts with /api/timstamp. If so, we split the request URL into two and grab the dateString part off the resulting array.

我知道要处理的代码很多,所以让我逐步介绍它。 我们在requestHandler中有一个else if语句,用于检查请求URL是否以/api/timstamp 。 如果是这样,我们split请求URL分为两个,并从结果数组中获取dateString部分。

If dateString is undefined or an empty string, it means that no date string was provided in the request. User story #3 dictates that we treat that situation as if the current date was requested, and that’s what getTimestamp(new Date()) does.

如果dateString undefined或为空字符串,则表示请求中未提供日期字符串。 用户故事#3指示我们将这种情况视为请求当前日期,这就是getTimestamp(new Date())所做的。

If a dateString does exist, we need to check if it’s a unix timestamp or an ISO-8601 date string (such as “2018-11-22”) so that we can decide whether to pass a number or a string to new Date(). Note that if you pass a unix timestamp as a string to new Date(), you will get an invalid result. That’s why this step is necessary.

如果dateString确实存在,我们需要检查它是否是unix时间戳或ISO-8601日期字符串(例如“ 2018-11-22”),以便我们决定是将数字还是字符串传递给new Date() 。 请注意,如果将unix时间戳记作为字符串传递给new Date() ,则会得到无效的结果。 这就是为什么必须执行此步骤的原因。

Next, we check if the date object stored in the date variable is valid. If so, we get the timestamp object as before, otherwise we set the timestamp variable to the structure for invalid dates as specified in user story #5.

接下来,我们检查存储在date变量中的date对象是否有效。 如果是这样,我们将像以前一样获得timestamp对象,否则我们将timestamp变量设置为用户故事5中指定的无效日期的结构。

The final step is to send the contents of the timestamp variable to the browser. In this case, we set the Content-Type header to application/json so that the response body is correctly interpreted as JSON. We also make sure that we are sending a valid JSON value by calling JSON.stringify(timestamp) and passing the output to the end method.

最后一步是将timestamp变量的内容发送到浏览器。 在这种情况下,我们将Content-Type标头设置为application/json以便将响应主体正确解释为JSON。 我们还通过调用JSON.stringify(timestamp)并将输出传递给end方法,确保发送有效的JSON值。

Now, test the app by passing a valid date string or unix timestamp after /api/timestamp/ or leave the date string out to get a JSON response for the current date. You can also try to pass an invalid date string to confirm that the service recognizes it as an invalid date.

现在,通过在/api/timestamp/之后传递有效的日期字符串或Unix时间戳来测试应用程序,或者不使用日期字符串以获取当前日期的JSON响应。 您也可以尝试传递无效的日期字符串,以确认服务将其识别为无效的日期。

实施404页面 (Implement a 404 page)

We’ve completed all the user stories for this application, but there’s one final thing I’d like us to do. If the browser requests a url that is not / or starts with /api/timestamp, we should set up the server to send a 404 response to the browser.

我们已经完成了该应用程序的所有用户案例,但是我希望我们做最后一件事。 如果浏览器请求的URL不是/或以/api/timestamp开头,则应将服务器设置为向浏览器发送404响应。

First, populate the views/404.html file with the following code:

首先,使用以下代码填充views/404.html文件:

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <meta name="viewport" content="width=device-width, initial-scale=1.0">  <meta http-equiv="X-UA-Compatible" content="ie=edge">  <title>404 Not found</title></head><body>  <h1>undefined is, unfortunately, not a function</h1>  <p>You just 404'd. Maybe you should head back to the <a href="/">homepage</a>.</p><script></script></body></html>

Next, modify the requestHandler function in index.js so that it looks like this:

接下来,修改index.jsrequestHandler函数,使其看起来像这样:

const requestHandler = (req, res) => {  if (req.url === "/") {    fs.readFile("views/index.html", (err, html) => {      if (err) throw err;
res.writeHead(200, { "Content-Type": "text/html" });      res.end(html);    });  } else if (req.url.startsWith("/api/timestamp")) {    const dateString = req.url.split("/api/timestamp/")[1];    let timestamp;
if (dateString === undefined || dateString.trim() === "") {      timestamp = getTimestamp(new Date());    } else {      const date = !isNaN(dateString)        ? new Date(parseInt(dateString))        : new Date(dateString);
if (!isNaN(date.getTime())) {        timestamp = getTimestamp(date);      } else {        timestamp = {          error: "invalid date"        };      }    }
res.writeHead(200, { "Content-Type": "application/json" });    res.end(JSON.stringify(timestamp));  } else {    fs.readFile("views/404.html", (err, html) => {      if (err) throw err;
res.writeHead(404, { "Content-Type": "text/html" });      res.end(html);    });  }};

I’ve added a final else block at the end of the requestHandler function that reads the contents of the views/404.html file and sends it to the browser for any URL that does not match / or /api/timestamp/:date_string?.

我在requestHandler函数的末尾添加了一个最后的else块,该块读取views/404.html文件的内容,并将其发送到浏览器以查找与//api/timestamp/:date_string?不匹配的任何URL /api/timestamp/:date_string?

Try it out. Enter a URL like http://localhost:4100/foo in your browser and confirm that it works!

试试看。 在浏览器中输入诸如http:// localhost:4100 / foo之类的URL,并确认其有效!

部署到Heroku (Deploy to Heroku)

What good is a timestamp microservice if no one can use it? Let’s share it with the world by deploying it to Heroku.

如果没有人可以使用时间戳微服务,那么它有什么用? 通过将其部署到Heroku与世界分享。

The first step is to sign up for a free Heroku account. Once your account is activated, follow this link to create a new app. Give it a unique name. I called mine “ayo-timestamp”.

第一步是注册一个免费的Heroku帐户 。 激活帐户后,请点击此链接创建一个新应用。 给它起一个唯一的名字。 我称我的为“ ayo-timestamp”。

Once your app is created, follow the instructions here to install the Heroku CLI on your machine. Then run the heroku login command in the terminal to login to your Heroku account.

创建应用后,请按照此处的说明在计算机上安装Heroku CLI。 然后在终端中运行heroku login命令登录到您的Heroku帐户。

Make sure you’ve initialised a git repository for your project. If not, run the git init command at the root of your project directory, then run the command below to set heroku as a remote for your git repo. Replace <app name> with the name of your application.

确保已为项目初始化了一个git存储库。 如果没有,请在项目目录的根目录下运行git init命令,然后运行以下命令将heroku设置为git repo的远程目录。 将<app na me>替换为<app na的名称。

heroku git:remote -a <app name>

Next, create a Procfile in the root of your project directory (touch Procfile) and paste in the following contents:

接下来,在您的项目目录的根目录中创建一个Procfile ( touch Procfile )并粘贴以下内容:

web: node index.js

Next, specify the version of Node you are running in your package.json file under the engines key. I specified version 10.9.0 since that’s the version I’m running on my computer. You should change that value to match the version of Node you have on your machine.

接下来,指定要在你正在运行的节点版本package.json下的文件engines关键。 我指定的版本是10.9.0因为那是我在计算机上运行的版本。 您应该更改该值以匹配您计算机上的Node版本。

{  "name": "timestamp-microservice",  "version": "1.0.0",  "description": "",  "main": "index.js",  "scripts": {    "test": "echo \"Error: no test specified\" && exit 1"  },  "keywords": [],  "author": "Ayo Isaiah",  "license": "MIT",  "engines": {    "node": "10.9.0"  }}

Finally, commit your code and push it to the Heroku remote using the following commands:

最后,使用以下命令提交代码并将其推送到Heroku远程服务器:

git add .git commit -m "Initial commit"git push heroku master

Once the deployment process is done, you can open https://<your-app-name>.heroku.com to view and test your project.

部署过程完成后,您可以打开https://<your-app-name>.hero ku.com来查看和测试您的项目。

结语 (Wrap up)

We’ve successfully built a timestamp microservice using only built-in Node modules, and deployed it to Heroku. To be sure, using web frameworks like Express is easier and more practical for non-trivial applications, but you’d be a much better Node developer if you’re at least a little familiar with its standard library before checking out what the community has to offer.

我们仅使用内置的Node模块成功构建了一个时间戳微服务,并将其部署到了Heroku。 可以肯定的是,对于非平凡的应用程序而言,使用Express这样的Web框架会更轻松,更实用,但是如果您在检查社区拥有的内容之前至少对其标准库有所了解,那么您将是一名更好的Node开发人员。提供。

I’ve got another tutorial that covers building a Node.js website using the Express as the web server and Pug for templating. You can check it out if you want some more practice with building Node projects and subscribe to my newsletter to get notified when I publish new tutorials.

我还有另一个教程,内容涉及使用Express作为Web服务器以及使用Pug进行模板构建Node.js网站 。 您可以查看是否需要更多有关构建Node项目的练习,并订阅我的时事通讯以在我发布新教程时得到通知。

Originally published at freshman.tech on November 22, 2018.

最初于2018年11月22日在freshman.tech上发布。

翻译自: https://www.freecodecamp.org/news/microservice-8edfdb9be811/

小程序 timestamp

小程序 timestamp_通过构建Timestamp微服务应用程序来学习Node.js相关推荐

  1. 1.Spring Cloud 构建微服务应用程序之概览

    1.Spring Cloud 构建微服务应用程序之概览 1.1 微服务发展史 1.2 为什么要学习微服务应用开发? 1.3 微服务和分布式之间的关系 1.4 微服务架构下构建分布式系统带来了哪些问题? ...

  2. 构建高性能微服务架构(网易)

    随着移动互联网时代的兴起,提供高性能.高可用性.高扩展性的服务已经不仅仅是大公司的专利,而逐渐成为所有互联网+公司的标配需求.本文介绍网易如何利用多年的互联网架构经验和网易蜂巢的平台,帮助客户进行架构 ...

  3. 构建高性能微服务架构 【摘自刘超】

    随着移动互联网时代的兴起,提供高性能.高可用性.高扩展性的服务已经不仅仅是大公司的专利,而逐渐成为所有互联网+公司的标配需求.本文介绍网易如何利用多年的互联网架构经验和网易蜂巢的平台,帮助客户进行架构 ...

  4. 【本人秃顶程序员】中小型互联网公司微服务实践-经验和教训

    ←←←←←←←←←←←← 我都秃顶了,还不点关注! 在开始之前我们先介绍一下几个概念,什么是微服务,它的特点是什么? Spring Boot/Cloud都做了那些事情?他们三者之间又有什么联系? 技术 ...

  5. 手把手0基础项目实战(一)——教你搭建一套可自动化构建的微服务框架(SpringBoot+Dubbo+Docker+Jenkins)......

    手把手0基础项目实战(一)--教你搭建一套可自动化构建的微服务框架(SpringBoot+Dubbo+Docker+Jenkins)... 原文: 手把手0基础项目实战(一)--教你搭建一套可自动化构 ...

  6. dubbo k8s 服务发现_工商银行基于 Dubbo 构建金融微服务架构的实践-服务发现篇

    作者 | 张远征来源|阿里巴巴云原生公众号 导读:Dubbo 作为分布式微服务框架,众多公司在实践中基于 Dubbo 进行分布式系统架构.重启开源后,我们不仅看到 Dubbo 3.0 最新的 Road ...

  7. 用Helm3构建多层微服务

    Helm是一款非常流行的k8s包管理工具.以前就一直想用它,但看到它产生的文件比k8s要复杂许多,就一直犹豫,不知道它的好处能不能抵消掉它的复杂度.但如果不用,而是用Kubectl来进行调式真的很麻烦 ...

  8. MSE 微服务治理发布企业版,助力企业构建完整微服务治理体系

    作者:十眠.流士 微服务(MicroServices) 架构是一把双刃剑,随着微服务架构复杂化,在大规模之下,再小的问题都会牵一发而动全身,因此微服务架构带来的效率.稳定性问题很可能会远大于微服务本身 ...

  9. 基于 Spring Security OAuth2和 JWT 构建保护微服务系统

    我们希望自己的微服务能够在用户登录之后才可以访问,而单独给每个微服务单独做用户权限模块就显得很弱了,从复用角度来说是需要重构的,从功能角度来说,也是欠缺的.尤其是前后端完全分离之后,我们的用户信息不一 ...

最新文章

  1. 第三十九篇 Python异常处理
  2. hdu 5254(暴力穷举)
  3. android纹理存储,android纹理文本
  4. 【大数据教程】MapReduce基本架构、统计每个人三次考试成绩的最高分,统计每一个人花费的总流量、按地区,统计每一个人花费的总流量
  5. 昨日搬至办公室的书籍
  6. 差值平方和匹配_机器学习实战 | 简单目标识别与意图分析之模板匹配
  7. linux下rman自动备份,linux 下rman 自动备份
  8. Java 多线程 —— wait 与 notify
  9. Shell判断参数是否为数字的6种方法(是否为整形)
  10. coreboot学习10:coreboot第一阶段学习小结
  11. 机器人领域会议期刊特点
  12. 华为网络技术培训笔记之常用网络工具(一)
  13. java后台对接app微信支付
  14. 安卓现盗号木马 威胁网银盗刷
  15. Istio进入1.7版本,Service Mesh 落地还有什么障碍?
  16. mix2s android p,待遇堪比“亲儿子” 小米MIX 2s迎来Android P升级
  17. PHP 通过身份证号判断年龄(周岁)
  18. 【深圳】大疆创新 - 测试/测试开发工程师 - 自动驾驶方向
  19. Android之内存泄漏调试学习与总结
  20. 【淘宝】商品列表页数据采集+商品销量数据采集代码

热门文章

  1. 服务器系统进不了系统错误代码,重启服务器进入点晴OA的Email模块时提示子系统密码错误,错误代码2027:800403e9,如何解决?...
  2. ubuntu安装mysql忘记密码并重置
  3. CAD删除Entity的所有XData(ResultBuffer)信息,C# .NET
  4. 母婴购物微信商城的设计与实现
  5. day06_类与对象
  6. 解封了 开始寻找牛人
  7. 001、element-ui前言
  8. 大学计算机VB考试试题,大学计算机二级VB测试题
  9. 斗地主含赖子的牌型判断算法
  10. 【信息安全技术】实验报告:木马及远程控制技术