Home >Web Front-end >JS Tutorial >A Guide to Serverless Deployment with Express and MongoDB

A Guide to Serverless Deployment with Express and MongoDB

Lisa Kudrow
Lisa KudrowOriginal
2025-02-10 12:47:091008browse

A Guide to Serverless Deployment with Express and MongoDB

This tutorial will demonstrate my preferred database-driven web application deployment workflow. It is for developers who want to achieve full-stack development in individual projects without having to set up and maintain complex multi-service infrastructure.

We will deploy a very basic web application written in Node.js and Express. It allows visitors to write and save notes, as well as read previously written notes. The data is stored in the MongoDB database. We will use GitHub Actions to create a CI https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712CD workflow to deploy our applications to AWS Lambda.

The focus is on simplicity, practicality and cost savings. Since AWS and MongoDB have very generous free tiers, you can learn for free. However, remember that if you don't want to end up paying a few cents, undeploy the application later. Since your app will be publicly available, it may theoretically outweigh the free tier in the long run. However, if you are planning to use this app extension for your own purposes, I can recommend this setup as it is very affordable for a moderately trafficted website.

You can find all the code for this tutorial on our GitHub account.

Key Points
  • Serverless deployment with AWS Lambda and MongoDB Atlas for cost-effective scalability and simplified server management.
  • Use GitHub Actions for continuous integration and deployment, automatically update and deploy Express applications to AWS Lambda.
  • Use Mongoose for object modeling, store application data in MongoDB, and efficiently manage database connections in a serverless environment.
  • Protect MongoDB Atlas instances by setting user authentication and whitelisting of IP addresses, although for sensitive data, consider a safer option.
  • Integrate AWS API Gateway to enhance application access and manageability, enabling public URLs and potential custom domain configurations.
  • Use Docker for local development setup for MongoDB and Node.js, ensuring a powerful environment for building and testing Express applications.

    Prerequisites

    Building an application requires some stuff. Make sure Node and Docker are installed on your system. To install Node, you can use Node Version Manager (nvm) (see some instructions here). For Docker, install the latest version of Docker Desktop for your operating system.

    Please note that we will use Docker to run MongoDB instances on our machine. Alternatively, you can manually install MongoDB Community Edition. You can find some instructions here.

    You also need to have an account on GitHub, MongoDB, and Amazon Web Services (AWS). When registering on AWS, you must enter your credit card number. As mentioned above, follow the steps in this tutorial will not exceed the free tier.

    Some preparatory knowledge about Node and Express may be helpful.

    Local development

    Okay, let's get started. We first need an empty folder with the new package.json file. If you do npm init, you can create one.

    We need to install the following dependencies:

    1. express, used to respond to HTTP requests from the client
    2. mongoose, used to communicate with our MongoDB database
    3. aws-serverless-express, for AWS Lambda to be able to call our application
    4. concurrently (as a development dependency), used to execute npm scripts in parallel

      Run the following command to install them:

      <code class="language-bash">npm install --save express mongoose aws-serverless-express && npm install --save-dev concurrently<https:><https:>
      <h3>1. MongoDB and mongoose<https:>
      <p> Since we use MongoDB database to store our data, running a database instance on a local machine is helpful for development. This is where we use the latest <em>mongo<https:> Docker image. If Docker is installed on your machine, just type docker run mongo in the terminal. The image will be extracted from dockerhub and launched in a new container. If you are not familiar with Docker, it doesn't matter. You just need to know that a MongoDB instance is running on your computer and you can communicate with it. <https:>
      <p>In order for our application to communicate with the database, we need to initialize a connection. We do this in a new file called mongoose.js.Mongoose是帮助我们进行MongoDB对象建模的库:<https:>
      <pre class="brush:php;toolbar:false"><code class="language-javascript">https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712 mongoose.js
      
      const mongoose = require("mongoose");
      
      const uri = process.env.MONGODB_URL;
      
      let connection;
      const connect = async () => {
        try {
          connection = await mongoose.createConnection(uri, {
            useNewUrlParser: true,
            useFindAndModify: false,
            useUnifiedTopology: true,
            bufferCommands: false, https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712 Disable mongoose buffering
            bufferMaxEntries: 0, https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712 and MongoDB driver buffering
          });
          return connection;
        } catch (e) {
          console.error("Could not connect to MongoDB...");
          throw e;
        }
      };
      
      function getConnection() {
        return connection;
      }
      
      module.exports = { connect, getConnection };<https:><https:>
      <p>此文件导出一个包含两个函数的对象。connect()创建一个到我们环境变量中指定位置的MongoDB的连接。该连接存储在一个名为connection的变量中。getConnection()只是返回connection变量。您可能想知道为什么我们不直接返回connection变量本身。这是因为Node.js在第一次加载后会缓存所需的模块。因此,我们使用一个函数从我们的mongoose.js模块中提取最新的connection变量。<https:>
      <p>现在我们的应用程序能够连接到数据库,我们也希望在其中存储数据——更具体地说,是我们可以在用户界面中编写的笔记。因此,我们将为我们的笔记创建一个数据模型。这在models文件夹内名为Notes.js的新文件中完成:<https:>
      <pre class="brush:php;toolbar:false"><code class="language-javascript">https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712 modelshttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712Notes.js
      
      const mongoose = require("mongoose");
      const { getConnection } = require("..https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712mongoose");
      const conn = getConnection();
      const Schema = mongoose.Schema;
      
      module.exports = conn.model(
        "Note",
        new Schema({ text: { type: String, required: true } })
      );<https:><https:>
      <p>在这里,我们从mongoose.js模块中提取当前连接,并在其上注册一个名为Note的模型。它有一个非常基本的模式,只包含一个名为text的必需属性,类型为String。Using this model, we can construct documents stored in the database. <https:>
      <h3>2. Express Application <https:>
      <p>Next, we create a simple Express application. Create a file named app.js in the project root directory.它具有以下内容:<https:>
      <pre class="brush:php;toolbar:false"><code class="language-javascript">https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712 app.js
      
      const express = require("express");
      
      const app = express();
      
      app.use(express.urlencoded({ extended: false }));
      
      app.get("https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712", async (req, res) => {
        try {
          const Note = require(".https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712modelshttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712Note");
          const notes = await Note.find({});
          return res.status(200).send(
            `
            <style>
                html {
                    text-align: center;
                    background-color: #93c5fd;
                    font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
                    color: white;
                    font-size: 2rem;
                }
      
                textarea {
                    resize: none;
                    border: 2px solid #9ca3af;
                    border-radius: 4px;
                    background-color: #f3f4f6;
                    padding: 0.5rem;
                    width: 90%;
                }
      
                button {
                    padding-left: 2rem;
                    padding-right: 2rem;
                    padding-top: 7px;
                    padding-bottom: 7px;
                    background-color: #f3f4f6;
                    border: 2px solid #9ca3af;
                    color: #4b5563;
                    border-radius: 4px;
                }
      
                p {
                    border-bottom: 2px solid;
                    padding: 1rem;
                    text-align: left;
                }
            <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712style>
            <form method="POST">
                <textarea name="text"><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712textarea><br>
                <button type="submit">Save<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712button>
            <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712form>
            <h1>My Notes<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h1>
            ${notes.map((n) => `<p>${n.text}<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>`).join("")}
            `
          );
        } catch (e) {
          return res.send(e);
        }
      });
      
      app.post("https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712", async (req, res) => {
        try {
          const Note = require(".https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712modelshttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712Note");
          const note = new Note(req.body);
          await note.save();
          return res.send("Note saved. <a href='https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712'>Refresh<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712a>");
        } catch (e) {
          return res.send(e);
        }
      });
      
      module.exports = app;<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712pre>
      <p> As I said, the app is very rude and is only used as a demonstration. First, we launch an Express application. We then tell it to parse the incoming request body for us, using the built-in urlencoded middleware to be able to use the submitted form data. The application has two methods to handle requests on the application root directory: <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <ul>
      <li>
      <p>app.get("https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712", ...) handles HTTP GET requests. When our user loads the page, it is called. We want to show them a simple page where they can type notes and save it. Additionally, we also want to display previously written notes. In the callback function of the request handler, we need our Note model. The model must be required within the callback function of our POST request handler, because it requires a current database connection - the connection may not exist when the app.js file is loaded for the first time. Then, we apply the find method to receive all notes in the database. This method returns a promise. So we wait for it to parse. Last but not least, we use the send method of the response object (res) to send the string back to the client. This string contains the HTML syntax that the browser renders as the actual HTML element. For each note in our database, we simply add a paragraph element that contains its text. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p>This is where you can convert this very humble example into a nice user interface. You are free to choose what to send to the client. For example, this could be a fully bundled client React application. You can also choose a server-side rendering method—for example, by using an Express view engine like Handlebars. Depending on what it is, you may need to add more routes to your application and serve static files like JS packages. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li>
      <li>
      <p>app.post("https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712", ...) handles HTTP POST requests. When the user saves their notes, it is called. Again, we first need our Note model. The request payload can be accessed through the body attribute of the request object (req). It contains the user-submitted text. We use it to create a new document and save it using the save method provided by Mongoose. Again, we wait for this asynchronous operation to complete, then notify the user and give them the possibility of refreshing the page. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li>
      <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712ul>
      <p>In order for our application to actually start listening to HTTP requests, we must call the listen method provided by Express.We will do this in a separate file dev.js added to the project root directory: <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <pre class="brush:php;toolbar:false"><code class="language-javascript">https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712 dev.js : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
      
      const app = require(".https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712app");
      const { connect } = require(".https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712mongoose");
      
      connect();
      
      const port = 4000;
      
      app.listen(port, () => {
        console.log(`app listening on port ${port}`);
      });<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712pre>
      <p>Here, we call the connect function in the mongoose.js file. This will initiate a database connection. Last but not least, we start listening for HTTP requests on port 4000. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p>Starting mongo Docker images with two separate commands and our application is a bit troublesome. So we add some scripts to our package.json file: <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <pre class="brush:php;toolbar:false"><code class="language-json">"scripts": {
        "start": "concurrently 'npm:mongoDB' 'npm:dev'",
        "dev": "MONGODB_URL=mongodb:https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4e dde557fd83712localhost:27017 node dev.js",
        "mongoDB": "docker run -p 27017:27017 mongo"
      }<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712pre>
      <p>mongoDB starts a MongoDB instance and maps container port 27017 to port 27017 of the local machine. dev launches our application and sets the environment variable MONGODB_URL loaded in the mongoose.js file to communicate with our database. The start script executes both scripts in parallel. Now we just need to run npm start in the terminal to start our application. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p>You can now access http: https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde55 in your browser 7fd83712localhost:4000 to load the application.<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p><img src="https:https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712img.php.cnhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712uploadhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712articlehttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712000https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712000https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712000https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712173916284121297.jpg" alt="A Guide to Serverless Deployment with Express and MongoDB " https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <h2><strong>Deployment<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712strong><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h2>
      <p>It's time to deploy our application. We will use Lambda functions on AWS, MongoDB Atlas, and AWS API Gateway. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <h3>1. What is a Lambda function? Why do we use them? <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
      <p>Lambda function is a way to execute code in response to HTTP requests without maintaining the server. They only run on demand, which means you don't have to pay for server time if no one calls your service. On the other hand, if many people call your service, AWS will automatically scale and will launch more Lambda instances. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p>As the name implies, Lambda functions are functions that you can fill in with whatever you want. There is only one exception: your code should not be stateful, because the Lambda instance will be closed once it is no longer executed. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p> We wrap the entire application in a Lambda function and deploy it on AWS Lambda. AWS Lambda has a very generous, unlimited free tier that includes one million free requests per month and 400,000 GB seconds! So you can safely experiment with the service and deploy multiple Lambda functions without paying for it. Remember, if you don't want to use them anymore, delete these functions. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <h3>2. Create AWS Lambda Function <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
      <p>Now, log in to your AWS Management Console and navigate to AWS Lambda. Under the <em> Functions <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em> section, click <em> to create a function <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em>. Before this, it is important that you have specified the region to deploy the service. On a desktop computer, you can select an area in the upper right corner of the management console. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p>Select <em> to create from scratch<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em> and name your function.I named it <em>express-lambda-example<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em>. Under <em>Runtime<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em>, select <em>Node.js 12x<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em> and create the function. You will see a window as shown below: <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p><img src="https:https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712img.php.cnhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712uploadhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712articlehttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712000https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712000https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712000https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712173916284443353.jpg" alt="A Guide to Serverless Deployment with Express and MongoDB " https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p>Our Lambda function already contains some test code. You can ignore this because we will overwrite it later. If you scroll down the page, you will see a section called <em>environment variable <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em>. Remember, in our previous local development script, we defined a variable called MONGODB_URL? We have to create the same variables here so that our Lambda instance can communicate with our database. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p> However, we have not run the database yet. We do not want to use our local machines for this purpose. That's why we're going to create a MongoDB Atlas Free Tier cluster. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <h3>3. Set up MongoDB Atlas Cloud Service<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
      <p>To create a free tier cluster, create an account on mongodb.com. During the registration process, you will be asked to select the cluster type. Choose the free shared cluster<em>. The next step is to name your project. Additionally, you can choose your favorite programming language. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em>
      <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>In the next step, you can choose cloud providers and regions. Since we already use AWS for our Node.js application, I recommend you select it and, if possible, select the same region you selected on AWS. In the next section, you can decide which level to use. Select the <p>M0 Sandbox<em> level. MongoDB does not recommend using this hierarchy in production environments, but for beginners it will provide everything you need.<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p><img src="https:https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712img.php.cnhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712uploadhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712articlehttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712000https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712000https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712000https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712173916284592009.jpg" alt="A Guide to Serverless Deployment with Express and MongoDB " https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p>A few minutes later, our cluster will be ready for use. The only thing missing now is access to it. Click <em> in the menu to access <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em> and create a new user. The authentication method is <em>password<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em>. Grants the user read and write permissions. After this is done, we need to whitelist the IP addresses that can access our database. You can do this under the <em> Network Access <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em> section. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p> Unfortunately, we don't know the IP of each Lambda instance that tries to connect to our cluster. So we will whitelist any IP addresses by adding 0.0.0.0 https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd837120. Please note that this is not recommended if you have sensitive data and want to ensure a high level of data protection. Our clusters are now protected only by the credentials we give to the database users. Setting up peer connections will be a possible solution to this problem. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p>Now, go back to your cluster and click <em>Connection<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em>. In the pop-up mode window, click <em> to connect your application <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em>. Then, select Node.js version 2.2.12 or later and copy the connection string. Go back to our Lambda Functions console on AWS, create a new environment variable called MONGODB_URL and paste the connection string in it. Make sure to replace the placeholder in the string with the credentials of the database user and the name of the database. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <h3>4. Make your application ready for use with AWS Lambda<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
      <p> In order for AWS Lambda to call our application, we have to set up a new entry script similar to what we did in the dev.js file.We will name it index.js, which has the following: <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <pre class="brush:php;toolbar:false"><code class="language-javascript">https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712 index. js
      const awsServerlessExpress = require("aws-serverless-express");
      const { connect } = require(".https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712mongoose");
      
      let connection = null;
      
      module.exports.handler = async (event, context) => {
        context.callbackWaitsForEmptyEventLoop = false;
      
        if (connection === null) connection = await connect();
        const app = require(".https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712app");
        const server = awsServerlessExpress.createServer(app);
        return awsServerlessExpress.proxy(server, event, context, "PROMISE").promise;
      };<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712pre>
      <p>Here, we use the aws-serverless-express library. It basically has the same functionality as the listen method in dev.js. It allows our application to process client requests in a Lambda environment. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p>Now, there is one important thing to note about our lambda.js file. Each time the Lambda function is called, the handler function is executed. Everything outside of the handler function is started once when the Lambda container is started and may persist between multiple Lambda calls. This is why we store MongoDB connection objects in the global scope of the file. Every time the handler function is run, it checks whether the connection has been started. If so, the function reuses it instead of reconnecting to the database every time. This is very important because it saves a lot of execution time. In order for the connection to persist in multiple calls, we need to set context.callbackWaitForEmptyEventLoop to false. You can read more about this feature here. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <h3>5. Deploy to AWS Lambda using GitHub Actions<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
      <p>The next step is to create a CI https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712CD workflow using GitHub Actions. This means that every time we push a code change to the GitHub repository, we want to trigger a pipeline. The pipeline automatically handles updating our Lambda functions on AWS. Jakob Lind describes this process well in his article "How to Set Up AWS Lambda and Automatic Deployment with Github Actions". I will briefly summarize the main parts. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p>To get GitHub to set up and start the workflow, we are at the path https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712.githubhttps://www.php.cn/link/29a9f8c8460e5 Create a call deploy.yml in e2be4edde557fd83712workflows file.它包含以下YAML代码:<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <pre class="brush:php;toolbar:false"><code class="language-yaml"># https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712.githubhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712workflowshttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712deploy.yml
      
      name: deploy to lambda
      on:
        push:
          branches:
            - main
      jobs:
        deploy:
          name: deploy
          strategy:
            matrix:
              node-version: [12.x]
          runs-on: ubuntu-latest
          steps:
            - uses: actionshttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712checkout@v1
            - name: Setup Nodejs
              uses: actionshttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712setup-node@v1
              with:
                node-version: ${{ matrix.node-version }}
            - name: npm install
              run: npm ci --production
            - name: zip
              uses: montudorhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712action-zip@v0.1.1
              with:
                args: zip -qq -r .https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712app.zip .https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712
            - name: push to lambda
              uses: appleboyhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712lambda-action@master
              with:
                aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY }}
                aws_secret_access_key: ${{ secrets.AWS_SECRET_KEY }}
                aws_region: eu-central-1 # 请替换为您的AWS区域
                function_name: express-lambda-example
                zip_file: app.zip<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712pre>
      <p>该文件告诉GitHub Actions在每次推送到存储库的主分支时执行一个名为deploy的作业。对我来说,将其仅限于主分支非常有用。因此,您可以安全地推送到您的开发分支,而不会将不需要的代码部署。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p>deploy作业只是安装所有必要的库,将整个项目压缩,并将其推送到AWS Lambda。请注意,YAML文件需要通过环境变量访问AWS访问密钥:AWS_ACCESS_KEY和AWS_SECRET_KEY。您可以通过在AWS上的身份和访问管理控制台中创建新用户来生成这些密钥。获得密钥后,您需要将它们另存为GitHub项目设置下的环境变量,位于<em>Secrets<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em>下。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p>要使您的应用程序在AWS Lambda上准备好,您需要提交您的代码并将其推送到GitHub存储库的主分支。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <h3>6. 使用AWS API Gateway使我们的应用程序可访问<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
      <p>现在我们的应用程序已准备好用于实时环境。但是,我们没有通过Web访问它的方法。这就是我们接下来使用AWS API Gateway所做的。Please note that API Gateway also has a free tier. However, this package is limited to 12 months. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p>In your AWS console, navigate to the API Gateway service and click <em>Create API<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em>, select <em>REST API<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em>, name it and save it. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p>To connect the API Gateway to our Lambda function, we create a new method that forwards any HTTP requests to our Lambda function. Therefore, in the <em>Operation<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em> drop-down menu, select <em>Create method<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em> and select <em>ANY<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em>. You should see a screen as shown in the following image. Make sure the <em>Use Lambda Agent Integration <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em> check box is selected. Enter the name of the Lambda function and save it. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p><img src="https:https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712img.php.cnhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712uploadhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712articlehttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712000https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712000https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712000https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712173916284649066.jpg" alt="A Guide to Serverless Deployment with Express and MongoDB " https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p>Next, we have to set up the Lambda proxy integration. This basically means that all client requests should be redirected as is to our Lambda function. Therefore, we create a new resource in the <em> Action<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em> drop-down menu. In the pop-up mode window, select the <em>Configure as proxy resource <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em> check box (see below) and save.<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p><img src="https:https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712img.php.cnhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712uploadhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712articlehttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712000https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712000https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712000https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712173916284977045.jpg" alt="A Guide to Serverless Deployment with Express and MongoDB " https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p> This will create another method we have to connect to the Lambda function. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p>Last but not least, we deploy our API by selecting <em>Deploy API<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em> in the <em> Action<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em> drop-down menu. In the pop-up window, select <em>[New Stage]<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em>, name the stage and deploy it. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p>That's it. You can access our application by clicking the <em> call URL<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em> found in the <em> Stage Editor<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em> of the created phase. <em>Call URL<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em> is the public URL mapped to our API Gateway. Of course, you can also use a custom domain to do this. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <h2><strong>Conclusion<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712strong><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h2>
      <p>You will see that deploying more complex applications that require databases is not necessarily difficult. Of course, the workflow I show you is far from perfect and lacks many of the features that large applications require in the long run. But for me, it has proven to be simple, practical and economical for websites with low and moderate traffic. I used a very similar technology stack to build and deploy JSchallenger. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <p>If you have any ideas or comments, please contact: @kueckelheim via Twitter. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <h2><strong>FAQs (FAQs) on Serverless Deployment with Express and MongoDB<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712strong><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h2>
      <h3>What are the benefits of using Express and MongoDB for serverless deployment? <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
      <p> Serverless deployment with Express and MongoDB has several advantages.First, it allows developers to focus on writing code without worrying about server management. This is because the serverless architecture automatically manages the server for you. Second, it is cost-effective because you only have to pay for the calculation time you consume. No fees are charged when your code is not running. Third, serverless deployments will automatically scale based on your workload size. This means that your application can handle more requests as demand increases without any manual intervention. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <h3>How to debug my serverless application? <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
      <p>Draining serverless applications can be a bit tricky due to its distributed nature. However, there are several ways you can use to debug your application. One of the most common methods is to use logging. You can record important information about application execution and then analyze these logs to find any problems. Another approach is to use distributed tracking tools such as AWS X-Ray. These tools provide insights on application performance and where bottlenecks occur. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <h3>Can I use Express middleware in a serverless application? <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
      <p>Yes, you can use Express middleware in serverless applications. Express middleware functions are functions that can access the request object (req), response object (res), and the next middleware function in the application request-response cycle. These functions can execute any code, change the request and response objects, end the request-response cycle, and call the next middleware function. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <h3>How to protect my serverless application? <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
      <p>Protecting serverless applications involves multiple steps. First, you should follow the principle of least permissions. This means you should only grant necessary permissions to your function. Second, you should encrypt sensitive data at rest and during transmission. Third, you should update your dependencies regularly to avoid any known vulnerabilities. Finally, you should monitor your application for any abnormal activity. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <h3>How to test my serverless application locally? <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
      <p>You can use tools such as Serverless Offline to test serverless applications locally. This tool emulates AWS Lambda and API Gateway on your on-premises machine, allowing you to test serverless applications without deploying it. You can also use unit testing frameworks like Jest to test your individual functions. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <h3>How to monitor my serverless application? <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
      <p>A variety of tools can be used to monitor serverless applications. AWS provides some monitoring tools such as CloudWatch and X-Ray.CloudWatch provides you with data and actionable insights to monitor your applications, understand and respond to system-wide performance changes, optimize resource utilization, and obtain a unified view of operational status. X-Ray helps developers analyze and debug production distributed applications, such as those built using microservice architectures. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <h3>How to deal with errors in serverless applications? <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
      <p> You can use the try-catch block in your code to handle errors in serverless applications. You can also use middleware functions to handle errors. Additionally, AWS Lambda automatically retrys the failed Lambda function twice, and you can configure other retry. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <h3>How to optimize the performance of serverless applications? <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
      <p>Optimizing the performance of a serverless application involves multiple steps. First, you should choose the appropriate memory size for your function. Second, you should minimize deployment package size to reduce cold boot time. Third, you should use a connection pool to reuse the database connection. Finally, you should use cache to reduce the number of database calls. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <h3>Can I use MongoDB Atlas with serverless applications? <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
      <p>Yes, you can use MongoDB Atlas with serverless applications. MongoDB Atlas is a fully managed cloud database developed by the same person who built MongoDB. It provides an easy way to deploy, operate and scale MongoDB on the cloud of your choice. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
      <h3>How to migrate my existing Express application to a serverless architecture? <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
      <p>Migrating an existing Express application to a serverless architecture involves multiple steps. First, you should refactor your application into smaller, stateless functions. Second, you should replace any middleware that is incompatible with the serverless architecture. Finally, you should thoroughly test your application to make sure it works properly in a serverless environment. <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p></style></code>

The above is the detailed content of A Guide to Serverless Deployment with Express and MongoDB. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn