By yugasun from yugasun.com/post/server… This article can be reproduced in full, but the original author and source need to be retained.

What is Serverless Component

Since the Serverless Component is based on the Serverless Framework, it is recommended to have a general understanding of the use of the Serverless command before reading this practical article, as it will be used in the following examples.

The Serverless Component aims to smooth out differences between cloud service platforms, and you can think of it as a dependency module that makes it easier to build applications. Serverless Component is now a community-driven ecosystem where you can browse and use all the components of the community to quickly build an app that you want.

How Serverless Component works

Based on the Serverless Component architecture, you can package any cloud service as a Component. This component will contain a serverless.yml configuration file and can be used simply by configuring it. Take @serverless/ Hceh-Express for example 🌰.

If we want to use it, just create a new project, Express-Demo, and modify the serverless.yml configuration as follows:

express:
  component: '@serverless/tencent-express'
  inputs:
    region: ap-shanghai
Copy the code

Since serverless framework deployment to cloud authentication is based on dotenV injection of global variables, it is necessary to add.env files in the root directory and configure the corresponding authentication parameters.

After that, we can easily write express-based interface services in app.js:

const express = require('express')
const app = express()
app.get('/'.function(req, res) {
  res.send('Hello Express')})// Don't forget to export, because the component wraps it and outputs the cloud function
module.exports = app
Copy the code

All the process logic behind this is implemented internally, including the deployment of cloud functions, generation of API gateways, and so on.

Here is a simple component dependency diagram:

This diagram provides a clear view of the benefits of the components, and with the community’s existing @serverless/ HlC-Express and @Serverless/HlC-Website components, we can quickly build the desired full-stack application.

Full stack application actual combat

Here’s how to quickly develop a full-stack Web application with the Serverless Component.

Before all steps, run the NPM install -g serverless command to install the Serverless CLI globally.

To prepare

Create the project directory fullstack-application-vue and add the API and Dashboard directories under the project directory fullstack-application-vue. Then add serverless. Yml and.env configuration files. The project directory structure is as follows:

├ ─ ─ the README. Md / / project documentation ├ ─ ─ the API / / Restful API back-end services ├ ─ ─ dashboard / / front page ├ ─ ─ the env / / right of tencent GuanJian cloud phase parameters: TENCENT_APP_ID, TENCENT_SECRET_ID, TENCENT_SECRET_KEY ├ ─ serverless.yml // serverless fileCopy the code

Back-end service development

Enter directory API, add app.js file, write express service code, add a route /, and return the current server time:

const express = require('express');
const cors = require('cors');
const app = express();

app.use(cors());
app.get('/', (req, res) => {
  res.send(JSON.stringfy({ message: `Server time: The ${new Date().toString()}` }));
});
module.exports = app;
Copy the code

Front-end page development

This example uses vue.js + Parcel’s front-end template, but of course you can use any front-end project scaffolding, such as Vue CLI-generated projects that vue.js officially recommends. You can directly copy the project template I prepared and write the entry file SRC /index.js:

// There is no env.js module initially, it will be generated automatically after the first deployment
require('.. /env');

const Vue = require('vue');

module.exports = new Vue({
  el: '#root'.data: {
    message: 'Click me! '.isVisible: true,},methods: {
    async queryServer() {
      const response = await fetch(window.env.apiUrl);
      const result = await response.json();
      this.message = result.message; ,}}});Copy the code

configuration

With the front-end and back-end code ready, we now need a simple configuration of the serverless.yml file:

name: fullstack-application-vue

frontend:
  component: '@serverless/tencent-website'
  Inputs: @serverless/ Tencent -website component input
  # configuration instructions specific reference: https://github.com/serverless-components/tencent-website/blob/master/docs/configure.md
  inputs:
    code:
      src: dist
      root: frontend
      hook: npm run build
    env:
    	After the following API service is deployed, obtain the corresponding API request path
      apiUrl: ${api.url}

api:
  component: '@serverless/tencent-express'
  Inputs: # inputs for @serverless/ 0700-Express
  # configuration instructions specific reference: https://github.com/serverless-components/tencent-express/blob/master/docs/configure.md
  inputs:
    code: ./api
    functionName: fullstack-vue-api
    apigatewayConf:
      protocol: https
Copy the code

First, the file defines two modules, frontend and API, which specify the dependent Serverless Component through the Component property, respectively. Inputs are accepted for a standard Serverless Component. The Component will process and deploy according to the inputs. For details, see the official configuration description of the Component.

The deployment of

With all of these steps completed, it’s time for the first deployment.

Why not direct joint development? Because the back-end services are cloud functions, all the code so far has been written locally, and the front-end page interface request link does not yet exist. Therefore, you need to deploy cloud functions to the cloud before you can perform front-end and back-end debugging. This is also my current pain point, because every time a back-end service is modified, it needs to be redeployed and then debugged for front-end development. If you have better suggestions, feel free to comment

To deploy, just run the serverless command, of course, if you want to view the DEBUG information in the deployment, you need to add the — DEBUG parameter as follows:

$ serverless
# or
$ serverless --debug
Copy the code

The terminal will then balabalabala~, output a bunch of DEBUG messages, and just see the green done:

The result is a full-stack application based on Serverless Component. Click on the link you’ve deployed to try it out

The online Demo

Database connection

Since it is full stack, how little database read and write? Next, you’ll see how to add read and write operations to the database.

To prepare

If you want to operate the database, you must first have a database instance, Tencent cloud Mysql cloud database is now also very cheap, you can buy a basic charge by volume 1 core 1G memory 1 hour charge is less than 40 cents, is not very cost-effective. SQL > select * from serverless; SQL > select * from users;

CREATE TABLE if not exists `test` ( `name` varchar (32) NOT NULL ,`email` varchar (64) NOT NULL ,`site` varchar (128) NOT NULL ) ENGINE = innodb DEFAULT CHARACTER SET = "utf8mb4" COLLATE = "utf8mb4_general_ci"
Copy the code

The front to modify

First modify the frontend/ SRC /index.js file to add related function operations:

require('.. /env');

const Vue = require('vue');
const axios = require('axios');
module.exports = new Vue({
  el: '#root'.data: {
    // ...
    form: {
      name: ' '.email: ' '.site: ' ',},userList: []},methods: {
    // ...
    // Get the user list
    async getUsers() {
      const res = await axios.get(window.env.apiUrl + 'users');
      this.userList = res.data && res.data.data || [];
    },
    // Add a new user
    async addUser() {
      const data = this.form;
      const res = await axios.post(window.env.apiUrl + 'users', data);
      console.log(res);
      if (res.data) {
        this.getUsers();
      }
    },
  },
  mounted() {
    // The view hangs behind to get the list of users
    this.getUsers(); }});Copy the code

You also need to modify the view template file frontend/index.html to add a user list and a user form to the page template:

<! -- user form -->
<section class="user-form" action="#">
  <div class="form-item">
    <label for="name">
      Name:
    </label>
    <input name="name" v-model="form.name" type="text" /><br />
  </div>
  <div class="form-item">
    <label for="email">
      Email:
    </label>
    <input name="email" v-model="form.email" type="email" /><br />
  </div>
  <div class="form-item">
    <label for="site">
      Site:
    </label>
    <input name="site" v-model="form.site" type="text" /><br />
  </div>
  <button @click="addUser">Submit</button>
</section>

<! -- user list -->
<section class="user-list">
  <ul v-if="userList.length > 0">
    <li v-for="item in userList" :key="item.id">
      <p>
        <b>Name: {{ item.name }}</b>
        <b>Email: {{ item.email }}</b>
        <b>Site: {{ item.site }}</b>
      </p>
    </li>
  </ul>
  <span v-else>No Data</span>
</section>
Copy the code

Note: If you are not familiar with vue. js syntax, please refer to the official documentation, of course, if you want to get started with vue. js development quickly, you can also read this tutorial from getting started to mastering Vue.

The back-end to modify

Env is used to configure database connection parameters. Add a. Env file to the API directory and fill the file with the previous database configuration, as shown in API /.env.example. Then add and install dotenv dependencies, add mysqL2 module for database operations, and body-Parser module for body parsing for POST requests.

After that, the back-end API was added for database reading and writing. The modified API /app.js code is as follows:

'use strict';
require('dotenv').config();
const express = require('express');
const cors = require('cors');
const mysql = require('mysql2');
const bodyParser = require('body-parser');

// init mysql connection
function initMysqlPool() {
  const { DB_HOST, DB_PORT, DB_DATABASE, DB_USER, DB_PASSWORD } = process.env;

  const promisePool = mysql
    .createPool({
      host: DB_HOST,
      user: DB_USER,
      port: DB_PORT,
      password: DB_PASSWORD,
      database: DB_DATABASE,
      connectionLimit: 1,
    })
    .promise();

  return promisePool;
}

const app = express();
app.use(bodyParser.json());
app.use(cors());

if(! app.promisePool) { app.promisePool = initMysqlPool(); } app.get('/', (req, res) => {
  res.send(JSON.stringify({ message: `Server time: The ${new Date().toString()}` }));
});

// get user list
app.get('/users'.async (req, res) => {
  const [data] = await app.promisePool.query('select * from users');
  res.send(
    JSON.stringify({
      data: data,
    }),
  );
});

// add new user
app.post('/users'.async (req, res) => {
  let result = ' ';
  try {
    const { name, email, site } = req.body;
    const [res] = await app.promisePool.query('INSERT into users SET ? ', {
      name: name,
      email: email,
      site: site,
    });
    result = {
      data: res && res.insertId,
      message: 'Insert Success'}; }catch (e) {
    result = {
      data: e,
      message: 'Insert Fail'}; } res.send(JSON.stringify(result));
});

module.exports = app;
Copy the code

Configuration changes

Here, the database access needs to be through Tencent cloud private network, so you need to configure private network (VPC) for cloud functions, and also need to configure the role that can operate the database (for role configuration, you can directly go to the role management page). Here, I created a role QCS_SCFFull, which can be used to access the database. Then modify the configuration in serverless.yml:

#...
api:
  component: '@serverless/tencent-express'
  # more configuration for @serverless/tencent-website,
  # refer to: https://github.com/serverless-components/tencent-express/blob/master/docs/configure.md
  inputs:
    code: ./api
    functionName: fullstack-vue-api
    role: QCS_SCFFull This role must have database access rights
    functionConf:
      This is a private network used to access the newly created database, which can be viewed on your database instance management page
      vpcConfig:
          vpcId: vpc-6n5x55kb
          subnetId: subnet-4cvr91js
    apigatewayConf:
      protocol: https
Copy the code

You just need to redeploy at the end.

Complete template repository

The online Demo

conclusion

Of course, the full stack solution is not so simple. Here is a brief introduction to how to quickly implement a full stack application using Serverless Component. There are more issues to consider when applying to a real business scenario. And the current community component is not perfect, many functions still need to be explored and discovered by ourselves. We also want more people to join the Serverless Component community and contribute more excellent components.