Summary: Currently, the process for developers to develop Serverless Package is relatively simple. Because the Serverless Devs developer tools already provide a relatively complete scaffolding capability, learn more in this article

The author | Jiang Yu (ali cloud Serverless product manager)

preface

Serverless Devs has been built with open source code and open ecological mode, so there are two ways for community users to participate in the construction of Serverless Devs:

1. Contributing code: Contributing code has a clear process and is a common way to participate in open source projects. The Contributor document of Serverless Devs can be referred to in the code contribution document.

2. Participate in contributing Package: You can develop applications or components and publish them to Serverless Registry for more people to learn, refer to or use; You can refer to this section;

Serverless Devs Package Introduction

Serverless Devs is a package management platform for all languages, such as Pypi in Python. Node. Js NPM.

The so-called package management platform, roughly speaking, manages “packages”, where “packages” often refer to some functions or capabilities that have been packaged by others, so that we can use them directly without having to reinvent the wheel.

To give two vivid examples, if we are in the field of artificial intelligence, we do not need to write various algorithms manually. We usually load some models quickly through Sklearn, Tensorflow and other corresponding packages, and then develop and improve them on this basis.

In the Serverless space, we would like to have a similar package management platform, Serverless Registry:

Serverless Regsitry, unlike Python’s Pypi and Node.js NPM, Package is divided into two classes: Component and Application.

Make a distinction between Component and Application in terms of vulgarity:

  • **Component: ** refers to a Component, similar to a script, through which you can do things. For example, deploy a function to a cloud platform, debug a function, view the log of a function, etc.
  • **Application: ** refers to the Application, similar to a case. For example, an Application allows users to quickly create a Hello World Application and an audio and video processing Application.

In the Specification of Serverless Devs, there is a difference diagram between the two:

The relationship between Component and Application is as follows: Application is the definition of an Application case that needs to be deployed online through Component.

Perhaps the above expression is a little abstract, in fact, can be explained with a graphic case. Such as:

  • If you create a face recognition Application using Python’s Tensorflow framework, Tensorflow is considered a Component, and the face recognition Application is considered an Application.
  • If you create a personal blog using node. js dependencies such as Express, Fs, and Path, the Express, Fs, and Path dependencies can be considered as different components, and the blog can be considered as an Application.
  • Serverless Registry Model
  • Serverless Package Model

The development Package

The process for developers to develop Serverless Package is relatively simple. This is because the Serverless Devs developer tools already provide relatively complete scaffolding capabilities.

Dev Template for Serverless Devs:

Select Component > Application > Application > Component > Application

The development of Component

When selecting Component Scaffolding, give the Component to be developed a name (e.g., DeployFunction) :

At this point, follow the system prompt to go to the Component project directory:

At this point, you can open the current project through the IDE and install dependencies through NPM (because Serverless Devs is a typescript-based project, component development only supports Typescript and Node.js) :

At this point, you can open the SRC /index.ts file in the project, and you can see that there is already a case:

import logger from ‘./common/logger’;

import { InputProps } from ‘./common/entity’;

Export default class ComponentDemo {/** * demo instance * @param inputs * @returns */ public async test(inputs: InputProps) { logger.debug(`input: ${JSON.stringify(inputs.props)}`); logger.info(‘command test’); return { hello: ‘world’ }; }}

In this file, we can see that the test(Inputs) method is a case that prints the inputs and returns Hello world, but we can learn a few things from this simple example:

Public methods are commands that users can use

In the project, we can write multiple methods to expose, currently only one test, but we can add any public methods that will become commands for the component. Such as:

public async test(inputs: InputProps) {

logger.debug(`input: ${JSON.stringify(inputs.props)}`);

logger.info(‘command test for test’);

return { hello: ‘world’ };

}

public async deploy(inputs: InputProps) {

logger.debug(`input: ${JSON.stringify(inputs.props)}`);

logger.info(‘command test for deploy’);

return { hello: ‘world’ };

}

At this point, when we use the component, the component has two commands: test and deploy. To verify our idea, we can compile the project in the basic development state: NPM run watch:

At this point, we can go to the example directory and test the deploy method, for example:

We can see from the s.yaml file below example that yamL has two services (component-test and component-test2).

And both services use the same component. So, after executing S deploy, we get the expected result: the deploy method is executed.

Similarly, we can execute the test command to see the effect:

The logic to be implemented can be implemented freely within a method

In other words, when the Serverless Devs tool loads a component, it actually passes the corresponding parameters to the specified method and executes that method. So, whatever you want to implement can be written in the corresponding method.

Take the Serverless Registry Component project as an example. In my project, I have a Login feature, so I implement the following in Login:

/** * demo login * @param inputs * @returns */ public async login(inputs: InputProps) {

const apts = { boolean: [‘help’], alias: {help: ‘h’}, }; const comParse = commandParse({args: inputs.args}, apts); if (comParse.data && comParse.data.help) { help([{ header: ‘Login’, content: `Log in to Serverless Registry` }, { header: ‘Usage’, content: ` s cli registry login
\` }, { header: ‘Options’, optionList: \[ { name: ‘token’, description: ‘\[Optional\] If you already have a token, you can configure it directly’, type: String, } \], }, { header: ‘Examples without Yaml’, content: \[ ‘ s cli registry login’, ‘ s cli registry login –token my-serverless-registry-token’, \], },\]); return; } const tempToken = comParse.data ? comParse.data.token : null let st = 0 let user if (tempToken) { const fd = await fse.openSync(\`{getRootHome()}/serverless-devs-platform.dat`, ‘w+’) await fse.writeSync(fd, tempToken) await fse.closeSync(fd) st = 1 } else {

Const token = random({length: 20}) const loginUrl = ‘github.com/login/oauth…

Logger. Warn (“Serverless Registry no longer provides independent registration function, but will uniformly adopt GitHub authorized login scheme.”) logger.info(“The system will attempt to automatically open the browser for authorization……” ) try { await sleep(2000) opn(loginUrl) } catch (e) { logger.info(“Failed to open the default address. Please try to open the following URL manually for authorization: “) logger.info(loginUrl) } await logger.task(‘Getting’, [ { title: ‘Getting login token …’, id: ‘get token’, task: async () => { for (let i = 0; i < 100; I++) {await sleep (2000) const tempResult = await the request (‘ registry. Devsapp. Cn/user/inform… ‘, {params: {token: token, }, }) if (! Tempresult.error && tempresult.safety_code) { Const fd = await fse.opensync (‘ {getRootHome()}/serverless-devs-platform.dat\ ‘, ‘w+’) await fse.writesync (fd, tempResult.safety\_code) await fse.closeSync(fd) st = 1 user = tempResult.login break } } }, } \]) } if (st == 1) { logger.log(\`{user ? user + ‘: ‘ : ”}Welcome to Serverless Devs Registry.`, “green”); } else { logger.error(“Login failed. Please log in to GitHub account on the pop-up page and authorize it, or try again later.”) } return null; }

There are several main things in this approach:

  1. Inputs: determine inputs for inputs;
  2. If the input parameter contains -h or –help, the corresponding help information is displayed.
  3. If the parameter entered by the user exists –token, the value of –token is saved to a file.
  4. If the user does not enter with –token, he/she can directly open the browser, access the login address of Serverless Registry, and obtain the login token.

In the same way, if it is a method or command to deploy a function, can we implement the package compression code in this, and then call the relevant create function, update the interface of the function to create the function? For example, if you want to delete a function, can you call the interface of the delete function inside?

So you can assume that whatever you want to implement can be implemented in the corresponding method.

Some specifications about the development process

Above we said that Serverless Devs will call this method with some parameters. What will the parameters look like? What’s the format? How do we parse it?

For example, what is the use of the return at the end of the project? How do I get the user’s key information in a project? How do I get the various parameters that a user writes in Yaml? How to obtain the parameters passed by the user when running a command?

In fact, these can be referred to: Serverless Devs Package development specification documentation component model code specification, here we can easily find:

Inputs have the structure:

{

“command”: “”,

“project”: {

“projectName”: “”,

“component”: “”,

“provider”: “”,

“access”: “”

},

“credentials”: {},

“prop”: {},

“args”: “”,

“argsObj”: []

}

The meanings of these parameters are as follows:

As a more concrete example, in the example code above, there is a test method, which is the function implementation method. When the user runs the test command, the system invokes the method with parameters. Take a real case as an example:

The component name is hexo, the core code of the component is shown above, and it has a test method. At this point, the user side Yaml is:

Edition: 1.0.0 # Command line YAML specification version, following Semantic Versioning specification name: FullStack # project name Access: XXX-account1 # Secret key alias

services:

HexoComponent:

component: hexo

props:

region: ‘cn-hangzhou’

codeUri: ‘./src’

S test mytest-a-b ABC: inputs in the component code:

{

“command”: “test”,

“project”: {

“projectName”: “HexoComponent”,

“component”: “hexo”,

“provider”: “alibaba”,

“access”: “release”

},

“credentials”: {

“AccountID”: “********”,

“AccessKeyID”: “********”,

“AccessKeySecret”: “********”

},

“prop”: {

“Region”: “cn-hangzhou”,

“CodeUri”: “./src”

},

“args”: “mytest -a -b abc”,

“argsObj”: [

“mytest”, “-a”, “-b”, “abc”

]

}

The test method prints logs and returns the final result to the command line tool: {“hello”: “world”}

For information on how to return help files, how to obtain key information, and how to parse user input, see the core package provided by Serverless Devs:

In the toolkit, we can see a number of methods to help us use it quickly:

For example, to obtain the user usage key, we can import the core package directly using the corresponding getCredential method:

  • Usage Method 1: If no parameter is passed, the system obtains the default key information

const { getCredential } = require(‘@serverless-devs/core’);

async function get() {

const c = await getCredential();

console.log(‘c’, c);

}

  • Usage Method 2: Set parameters to obtain the specified key information

const { getCredential } = require(‘@serverless-devs/core’); Async function get() {inputs const inputs = {}; const c = await getCredential(inputs, ‘custom’, ‘AccountIdByCustom’, ‘SecretIDByCustom’); console.log(‘c’, c); }

Component Description

After completing our component function writing, we can describe the component. The so-called component description is to tell Serverless Registry what it is and what functions it has. Publish. Yaml:

For the contents of this file and the values of some parameters, refer to the component model metadata.

Of course, there are no other files in the Serverless Package specification other than publish.yaml:

Can change | | – # SRC directory name └ ─ ─ code directory | – package. Json: need to define a good main | – publish. Yaml: resource description of project | – readme. Md: project introduction | – version. The md: Version Updates

Among them:

The latest version of the specification (version 0.0.2) will be available in the near future. Different from version 0.0.1, the Properties parameter of the new version will follow the JSON Scheme specification. For now, please refer to pr#386.

Development and Application

When selecting Application Scaffolding, you need to name the Application to be developed (for example, HelloWorld) :

Application development in the Serverless Package is relatively simple and can be wrapped as an Application by any programming language and any project that can be deployed through the Serverless Devs developer tools.

Or more accurately, as long as you currently have a project that can be deployed directly with Serverless Devs, you can:

  1. S init Creates an application template
  2. Desensitized your project directly into the SRC directory
  3. Describe the application, such as editing publish.yaml, version.md, readme.md, etc

For details, please refer to the application model documentation:

Special format: In the application model, the SRC/S.aml file is required as the resource and behavior description file identified and used by Serverless Devs. In this file, users may need to fill in some contents, such as the name of the user’s key and the region where the user deploys the service. At this point, you can refer to:

“{{access}}” : directly remind the user to enter a parameter like access as a required parameter in Yaml; ‘{{buckets | alibaba oss bucket}}’ : : just remind users need to input the bucket a parameters, such as the necessary parameters in Yaml, and after | in the content of the “alibaba oss bucket” as explain the meaning of this parameter. For example, in s.aml of an application, it is:

Edition: 1.0.0 access: “{{access}}”

services:

website-starter:

component: devsapp/website

actions:

pre-deploy:

– run: npm install

path: ./

– run: npm run build

path: ./

props:

bucket: ‘{{ bucket | alibaba oss bucket }}’

src:

codeUri: ./

publishDir: ./build

index: index.html

region: cn-hangzhou

hosts:

– host: auto

Release the Package

After the development of the Serverless Package is complete, you can also publish into Registry for wider use.

Release to making/Gitee

Posting to Github or Gitee is simple:

  1. Create a Repo (Repository)
  2. Push the entire application or component to the repository
  3. Release a Release: At this point, on the client side, users can switch the Registry through S Set Registry to use the corresponding functions. For example, if MY Github account is AnyCodes, I can create a repository called Demo. At this point, I can upload my components/applications to this repository and then publish a Release. At this point, I’m on the client side, switch Registry to Github, and then I can:
  • When using components, specify the component name repository, such as Anycodes /demo
  • It is also possible to specify applications directly when initializing them, such as anyCodes/Application

Publish to Serverless Registry

To publish a Package to Serverless Registry, consider using the Serverless Registry Component.

(The Serverless Registry client tool is also a Component, so you can consider the Serverless Registry Component project itself a best practice for the current article.)

After completing the component or application development process, you need to:

  1. To register and login to Serverless Registry, you essentially execute s cli Registry login
  2. To publish a component is actually S cli Registry publish

Of course, the Serverless Registry Component project has many other functions besides login and publishing, such as:

  • View the Package published by the current login account
  • View the version information of a Package
  • View the version information specified by a Package
  • Deletes a specified version of the Package
  • Update the login token

conclusion

As we all know, the development of a complete technical architecture is inseparable from the enabling of the ecological community, whether it is Docker’s Dockerhub, Python’s Pypi, or Node.js’s NPM. Ecological activity is positively correlated with the happiness of our developers.

We also hope that Serverless Devs can play with Serverless architecture with more people through an open ecosystem like Serverless Regsitry. We also look forward to more excellent packages being widely used.

The original link

This article is the original content of Aliyun and shall not be reproduced without permission.