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

preface

The last article on the Serverless Component-based full-stack solution described what the Serverless Component is and how to develop a full-stack application using the Serverless Component. But the community isn’t quite there yet, so what happens when we need a component that we don’t already have?

Instead of submitting an issue to an official stating the need, it’s better to masturbate yourself

Serverless Component runtime mechanism

Before we start development, let’s take a look at how Serverless Component works:

Each Serverless Component is essentially an NPM package that you can install directly with the NPM install command. When executing Serverless –debug deployment in an application that relies on Serverless Component, it first reads the Component argument in the Serverless. Yml file specifying the Component module. It is automatically installed locally, just like the NPM package, and then automatically injects the component module, executing the default function in the component (described later) to complete the deployment process.

Development steps

A complete component development process should include the following processes:

  1. Identify functional requirements
  2. Define component configuration: input and output parameters
  3. Component development: default function, remove function (optional)
  4. The test component
  5. Release NPM package

Next, Tencent cloud CDN component will be realized step by step according to the above steps.

1. Identify functional requirements

Tencent cloud CDN console has provided the function of manually configuring accelerated domain names, but as a lazy programmer, “manual” has always been a problem I tried to avoid. So went to see Tencent cloud documents, see whether the official has provided the corresponding convenient way. Sure enough, Tencent cloud API has provided relevant interfaces, so why don’t we use API to implement a CDN component that can help us automatically configure?

The requirement was clear: develop a component that could automatically configure the CDN accelerated domain name, helping us save manual configuration time.

2. Define the component configuration

To add a CDN domain name, two Tencent cloud API interfaces are required: add accelerated domain name and HTTPS configuration. After reading the two interface documents, a configuration description file, config.md, is summarized as follows:

MyCDN:
  component: '@serverless/tencent-cdn'
  inputs:
    host: abc.com
    hostType: cos
    origin: www.test.com
    backupOrigin: www.test.com
    serviceType: web
    fullUrl: on
    fwdHost: ww.test.com
    cache:
      - type: 0
        rule: all
        time: 1000
      - type: 0
        rule: all
        time: 1000
    cacheMode: simple
    refer:
      - type: 1
        list:
          - 'qq.baidu.com'
          - '*.baidu.com'
    accessIp:
      type: 1
      list:
        - '2.'
        - '2.3.4.5'
    https:
      certId: 123
      cert: 123
      privateKey: 123
      http2: off
      httpsType: 2
      forceSwitch: 2 -
Copy the code

Inputs are input parameters of a component. These parameters are copied from the interface document: inputs are inputs for the component.

The configuration of a non-service framework is a YAML file, so you need to map the API parameters to the YAML specification when defining the component configuration. In yamL files, for example, the – symbol is used to define arrays. If you are not familiar with YAML syntax, check out this yamL language tutorial.

Once the input of the component is defined, you also need to define the output. You just need to roughly organize the API request return structure, as concise as possible:

{
	host: 'abc.com',
	hostId: '123'
	origin: 'www.test.com',
	cname: 'www.test.com.cdn.dnsv1.com',
	https: true
}
Copy the code

3. Component development

For a standard Serverless Component, the structure is as follows:

// serverless.js
const { Component } = require('@serverless/core')
class MyComponent extends Component {
  /* * Default (mandatory) * - Default is the function used to execute, prepare and update your build * - executing '$serverless' will run this function * - You can run this function by running  the "$ serverless" command */
  async default(inputs = {}) {
    return{}}/* * Remove (optional) * - If your component needs to Remove infrastructure, you are recommended to add it * - executing the command '$serverless Remove' will run this function */
  async remove(inputs = {}) {
    return{}}/* * Anything (optional) * - If you want to publish components with additional functionality, you can write the logic in a function whose name can be customized * - executing the command '$serverless Anything' will run this function */
  async anything(inputs = {}) {
    return{}}}module.exports = MyComponent
Copy the code

Now that you know the structure of the component, it’s time to start developing

3.1 Initializing the Project

Create project directory 0700-cdn, execute NPM init to initialize project, follow command instructions, fill in relevant information:

$ npm initThis utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sensible defaults. See `npm help json` for definitive documentation on these fields and exactly what they do. Use `npm install <pkg>` afterwards to install a package and save it as a dependency in the package.json file. Press ^C at any time to quit. Package name: (CDN-module) Tencent - CDN version: (1.0.0) description: Tencent Cloud CDN Component entry point: (index.js) serverless.js test command: git repository: keywords: cdn,serverless,serverless-component,serverlesscomponent,tencent author: yugasun license: (ISC) MIT About to write to /Users/yugasun/Desktop/Develop/serverless/cdn-module/package.json: { "name": "Tencent Cloud CDN Component", "main": "serverless.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [ "cdn", "serverless", "serverless-component", "serverlesscomponent", "tencent" ], "author": "yugasun", "license": "MIT" } Is this OK? (yes)Copy the code

Then create a new serverless.js file and copy the template code above into the serverless.js file.

3.2 Writing the default function

Default function code, here will not be posted, a bit more O (╯□╰ O) O.

Inputs: specify interface request parameters, then request the inputs, and perform configuration.

For Tencent cloud API, all interface requests need authentication, so we need to instantiate a Capi first, as follows:

import { Capi } from '@tencent-sdk/capi'
const capi = new Capi({
	SecretId: this.context.credentials.tencent.SecretId,
  SecretKey: this.context.credentials.tencent.SecretKey,
  ServiceType: 'cdn',})Copy the code

Note: the documentation about the request cloud API library @hceh-SDK/CAPi is quite comprehensive, of course you can also see the source code here.

It needs to be introduced into SecretId, SecretKey, ServiceType three parameters, SecretId and SecretKey can through this. Context. Credentials. Tencent to obtain, Perform serverless command executes, it will be based on user project root directory configuration. The env file, automatic into this. Context. Credentials. Tencent. ServiceType indicates the current ServiceType, which is defined by Tencent cloud API. You only need to set parameters for different services.

The credentials listed in this.context.credentials vary from cloud service provider to cloud service provider. For example, Tencent cloud is Tencent and AWS is AWS. The source code for configuring the properties of all cloud service providers can be found at @serverless/cli

Then request a new accelerated domain name interface:

// cdnInputs is our assembled request parameter
await AddCdnHost(capi, cdnInputs)
Copy the code

There is an important point here: the CDN will not be successfully deployed immediately after the successful return of the request for the new accelerated domain name interface, which takes time. Therefore, after the implementation, we need to train the status of the current new domain name, and when the deployment is successful, we can proceed with the subsequent logic.

3.3 Component Status Saving

When the Serverless Component executes the default function, it generates some state. For example, if the CDN name is successfully added, it will generate a hostId, which we can save in this. State. It will save this.state to a file named template.mycdn. json (MyCDN is the name of the current Serverless application I defined) in the.serverless folder at the root of the project for later use when building and deleting components.

3.4 Writing the remove function

Serverless Component removes the logic that when the Serverless remove command is executed, it reads the state file saved to. Serverless by the default function execution. Inject it into this.state, and then we can remove it based on the value in state, for example I’m going to use host here, because deleting the accelerated domain name interface requires passing the host parameter.

3.5 Improving documentation

README for open source projects must be written clearly to facilitate smooth use and development of developers.

4. Test components

The Serverless Framework provides a good way to debug locally. The Component in the application Serverless. Yml can specify a local project path. For example, in The 0700-cdn directory, create the test folder and add the serverless.yml configuration as follows:

MyCDN:
  component: ../
  inputs:
    host: abc.com
    .
Copy the code

Here.. / is the relative path, because the serverless. Js file of the 0700-cdn component is in the 0700-cdn root directory, after which we can go to the test directory and perform deployment and removal operations to test our component.

Note: Although a Serverless Component is an NPM module, we can specify any file entry in the project via the main property in package.json, without the Serverless. The serverless command cannot be debugged from the local path specified by component.

5. Publish the NPM package

To publish the NPM package, you need to have an NPM account first. Please go to the NPM official website to register, and then execute NPM login to login to your account.

After testing it, you can publish to the NPM repository.

The source code

Final implementation of the source code: @serverless/ Tencent – CDN.

A component reference

For each component instance, there is a load method that we can use to load other components as follows:

const cdnComp = await this.load('@serverless/tencent-cdn'.'cdnComp');
Copy the code

With this feature, we can implement many higher-level components, such as @serverless/ Tencent -website is a good example.

As for how to assemble your components to meet your own needs, it’s up to you to do whatever you want. Do your part in the community

Component development template

Here is a Serverless Component development template for Tencent Cloud to help you quickly develop a Serverless Component.

Template link

reference

  • How to write your first Serverless Component
  • Building Serverless Components