The fun local command is a subcommand of Funcraft. The fun local command can be run to simulate functions in Function Compute on premises and provides step-by-step debugging. These features enable Function Compute to eliminate the disadvantages in development compared with traditional applications and provide a new troubleshooting method.
Background information
The fun local command provides the fun local invoke and fun local start subcommands. You can run the fun local invoke command to invoke event functions and run the fun local start command to invoke HTTP trigger functions and event functions on premises. You can run the fun local start command in a browser to invoke an HTTP trigger function. When you run the fun local start command to invoke an event function, you can call the InvokeFunction operation or use an SDK to invoke the function. For more information, see InvokeFunction and Supported SDKs.
The fun local command is supported by the graphic plug-ins of different integrated development environments (IDEs), such as Visual Studio Code (VS Code), IntelliJ IDEA, and PyCharm. Compared with command line tools, these plug-ins provide enhanced graphical operations.
- If you use VS Code, we recommend that you use Aliyun Serverless VSCode Extension. For more information, see Aliyun Serverless VSCode Extension.
- If you use IntelliJ IDEA or PyCharm, we recommend that you use Alibaba Cloud Toolkit.
Syntax of the fun local invoke command
$ fun local invoke -h
Usage: invoke [options] <[service/]function>
Run your serverless application locally for quick development & testing.
Options:
-d, --debug-port <port> used for local debugging
-c, --config <ide> print out ide debug configuration. Options are VSCode
-e, --event <path> event file containing event data passed to the function
-h, --help output usage information
- Invoke functions on premises
The command that is used to invoke functions is in the following syntax:
The options and service parameters are optional. You can run the fun local invoke command to invoke a function by using the following syntax to specify a function name or both service and function names:fun local invoke [options] <[service/]function>
If you need to precisely specify a function, you can specify it in the service/function format.fun local invoke function fun local invoke service/function
Note If the template.yml file contains multiple services, and multiple services contain functions with the same name, only the first function that matches is invoked when you specify a function name.Invoke Java functions on premises
Java is a compiled language. You must compile the code of functions that is written in Java before you invoke the functions. You can use the fun build [function] command to compile the code of a function. For example, run the following command to compile a function named java8:
After you run the preceding command, the following log is displayed:fun build java8
After you compile the code of the function, you can run the fun local invoke command to invoke the function.using template: template.yml start building function dependencies without docker building localdemo/java8 running task flow MavenTaskFlow running task: MavenCompileTask running task: MavenCopyDependencies running task: CopyMavenArtifacts Build Success Built artifacts: .fun/build/artifacts Built template: .fun/build/artifacts/template.yml Tips for next step====================== * Invoke Event Function: fun local invoke * Invoke Http Function: fun local start * Deploy Resources: fun deploy
- Debug functions on premises
You can add the
-d, --debug-port
option to the fun local invoke command to step through a function on premises. The fun local command provides debugging methods that are based on the debugging protocol used by all programming languages. You can use the remote debugging method provided by the programming language that you use.- Debug Node.js and Python functions on premises
Functions that run in Node.js 6, Node.js 8, Python 2.7, Python 3, and Java 8 are debugged in a similar way. Node.js 8 is used in the following example:
You can run the fun local invoke nodejs8 command to invoke a function named nodejs8. To debug the function, you can add the -d parameter and specify the corresponding port number.
For example, you can run the following command to set the debug port number to 3000 and debug the function:fun local invoke -d 3000 nodejs8
We recommend that you add the --config parameter to display the IDE configurations used for debugging.fun local invoke -d 3000 --config VSCode nodejs8
The following log is displayed:
The function is blocked and continues to be executed only after you configure the IDE. The following part describes how to configure VS Code and debug functions in VS Code:skip pulling images ... you can paste these config to .vscode/launch.json, and then attach to your running function ///////////////// config begin ///////////////// { "version": "0.2.0", "configurations": [ { "name": "fc/localdemo/nodejs8", "type": "node", "request": "attach", "address": "localhost", "port": 3000, "localRoot": "/Users/tan/code/fun/examples/local/nodejs8", "remoteRoot": "/code", "protocol": "inspect", "stopOnEntry": false } ] } ///////////////// config end ///////////////// Debugger listening on ws://0.0.0.0:3000/b65c288b-bd6a-4791-849b-b03e0d16b0ce For help see https://nodejs.org/en/docs/inspector
The VS Code configuration is required only when you debug functions for the first time. If you have configured VS Code, you do not need to configure VS Code again.
- Configure VS Code.
- Create a launch.json file in VS Code.
- Copy the configurations that are displayed between the config begin and config end
comments in the preceding log to the launch.json file.
- Find the function in the DEBUG drop-down list.
VS Code configuration is complete. For more information about VS Code configuration, visit Debugging.
- Create a launch.json file in VS Code.
- Debug functions in VS Code
- After VS Code is configured, you can click the editor margin to create breakpoints
and click the Start Debugging icon.
- The following example shows how to step through the function named nodejs8 on premises.
- After VS Code is configured, you can click the editor margin to create breakpoints
and click the Start Debugging icon.
- Configure VS Code.
- Debug Java functions on premises
- Debug Java functions in VS Code
You must install the Language Support for Java™ by Red Hat and Debugger for Java plug-ins before you debug Java functions in VS Code. For more information about how to install plug-ins in the VS Code marketplace, visit Java in Visual Studio Code.
The following example shows how to debug a Java function in VS Code.
- Debug Java functions in IntelliJ IDEA
In the top navigation bar, choose.
- Click the Create icon and select Remote to create a remote debug configuration.
- Enter a name in the Name field and set the port number to 3000.
- The following example shows how to configure remote debugging in IntelliJ IDEA.
- Click the Create icon and select Remote to create a remote debug configuration.
- Debug functions in IntelliJ IDEA
Run the following command to invoke and debug a Java function:
fun local invoke -d 3000 java8
The function is blocked. You must configure IntelliJ IDEA to start debugging. Choose
in the top navigation bar or click the Debug icon in the tool bar to start debugging.The following example shows how to perform remote debugging in IntelliJ IDEA.
- Debug Java functions in VS Code
- Debug Node.js and Python functions on premises
- Debug PHP functions on premises
The process of debugging PHP functions is different from that of debugging other types of functions.
PHP functions are invoked by running the fun local invoke php72 command and debugged by adding the -d parameter, in the same manner as other types of functions.fun local invoke -d 3000 --config VSCode php72
However, when you invoke and debug a PHP function, the PHP function is not blocked and does not wait for the VS Code debugger to connect.skip pulling images ... you can paste these config to .vscode/launch.json, and then attach to your running function ///////////////// config begin ///////////////// { "version": "0.2.0", "configurations": [ { "name": "fc/localdemo/php72", "type": "php", "request": "launch", "port": 3000, "stopOnEntry": false, "pathMappings": { "/code": "/Users/tan/code/fun/examples/local/php7.2" }, "ignore": [ "/var/fc/runtime/**" ] } ] } ///////////////// config end ///////////////// FunctionCompute php7.2 runtime inited. FC Invoke Start RequestId: 6e8f7ed7-653d-4a6a-94cc-1ef0d028e4b4 FC Invoke End RequestId: 6e8f7ed7-653d-4a6a-94cc-1ef0d028e4b4 hello world RequestId: 6e8f7ed7-653d-4a6a-94cc-1ef0d028e4b4 Billed Duration: 48 ms Memory Size: 1998 MB Max Memory Used: 58 MB
This is because you must first start the VS Code debugger for PHP functions.
The process of starting the VS Code debugger for PHP functions is the same as that for other types of functions: You must copy the configurations in the preceding log to the launch.json file and click the Start Debugging icon. Then, you can invoke the PHP function in debugging mode and debug the function on the terminal.fun local invoke -d 3000 php72
- Construct trigger events
Function Compute provides various triggers, such as Object Storage Service (OSS) triggers, Log Service triggers, and Alibaba Cloud CDN event triggers. To simulate the Function Compute environment, you must construct trigger events when you invoke or debug functions on premises.
A trigger event can be readable JSON configurations or non-readable binary data. The following example shows a JSON event:{ "testKey": "testValue" }
You can use one of the following methods to pass the event to your function:- Pipe:
echo '{"testKey": "testValue"}' | fun local invoke nodejs8
- File: Create a JSON file, such as
event.json
, to store the JSON event. Use the -e parameter to specify the file name in the command: fun local invoke -e event.json nodejs8. - Redirection:
fun local invoke nodejs8 < event.json
orfun local invoke nodejs8 <<< '{"testKey": "testValue"}'
. For more information, visit Bash Input Redirection.
- Pipe:
fun local start
Usage: fun local start [options]
Allows you to run the Function Compute application locally for quick development & testing.
It will start an http server locally to receive requests for http triggers and apis.
It scans all functions in template.yml. If the resource type is HTTP, it will be registered to this http server, which can be triggered by the browser or some http tools.
For other types of functions, they will be registered as apis, which can be called by sdk in each language or directly via api.
Function Compute will look up the code by CodeUri in template.yml.
For interpreted languages, such as node, python, php, the modified code will take effect immediately, without restarting the http server.
For compiled languages such as Java, we recommend you set CodeUri to the compiled or packaged location.
Once compiled or packaged result changed, the modified code will take effect without restarting the http server.
Options:
-d, --debug-port <port> specify the sandboxed container starting in debug mode, and exposing this port on localhost
-c, --config <ide/debugger> output ide debug configuration. Options are vscode
-h, --help output usage information
- Invoke HTTP trigger functions on premises
Run the following command:
fun local start [options]
The options parameter is optional.
After you run the fun local start command, Funcraft starts an HTTP server to provide HTTP services. Then, Funcraft registers functions that are described in the template.yml file and configured with HTTP triggers at the HTTP server. After the registration, you can trigger the functions by using HTTP tools, such as browsers.
For example, all HTTP trigger information is displayed after you run the fun local start command in the local_http path:You can trigger an HTTP trigger function by using the corresponding URL.
The following example shows how to trigger an HTTP trigger function in Node.js. The process also applies to Python and PHP. - Debug HTTP trigger functions on premises
You can add the -d, --debug-port option to debug HTTP trigger functions on premises. The process is similar to the process of using events to trigger functions. You can also add the -c, --config option to display the IDE configurations.
Run the fun local start --debug 3000 --config vscode command to start a service. The following result shows that all the functions described in the template.yml file are registered.Select a URL based on the service name, function name, or HTTP trigger name and open the URL by using a browser. The browser generates no responses, and the terminal displays the following log:
Copy the configurations in the preceding log to the VS Code debugger, create breakpoints, and click the Start Debugging icon.skip pulling image aliyunfc/runtime-python3.6:1.2.0... you can paste these config to .vscode/launch.json, and then attach to your running function ///////////////// config begin ///////////////// { "version": "0.2.0", "configurations": [ { "name": "fc/local-http-demo/python3", "type": "python", "request": "attach", "host": "localhost", "port": 3000, "pathMappings": [ { "localRoot": "/Users/tan/fun_local_http_demo/python3", "remoteRoot": "/code" } ] } ] } ///////////////// config end ///////////////// FunctionCompute python3 runtime inited. FC Invoke Start RequestId: 04c57fba-cbe9-4c1f-8c57-f8e0b539fa08
The following example shows how to debug an HTTP trigger function in Python. This process also applies to Node.js and PHP. - Perform a hot load
A hot load is performed when you invoke and debug HTTP trigger functions on premises.
Assume that you have started an on-premises service by running the fun local start command and modified the code of a function. In this case, you can refresh the web page or trigger the function again to invoke the modified function without the need to reload the on-premises service.
The following example shows the hot load result of a Node.js function. This process also applies to PHP and Python functions. You must run the npm install command in the function directory in advance to initialize the Node.js modules on which the function depends.
- Call API operations to invoke and debug functions on premises
The command syntax is the same as that used to invoke an HTTP trigger function.
fun local start [options]
The options parameter is optional.
After you run the fun local start command, Funcraft starts an HTTP server to provide HTTP services. Then, Funcraft registers functions that are described in the template.yml file and not configured with HTTP triggers at the HTTP server. After the registration, you can call the InvokeFunction operation or use SDKs to invoke the functions. For more information, see List of operations by function and Supported SDKs.
If you invoke the functions by calling API operations, signature authentication is required.We recommend that you use SDKs to invoke functions. Run the fun local start command to run a service. The following log is displayed:
After the service is started, you can use SDK for Python to invoke functions.$ fun local start api localdemo/php72 was registered url: http://localhost:8000/2016-08-15/services/localdemo/functions/php72/invocations/ api localdemo/python27 was registered url: http://localhost:8000/2016-08-15/services/localdemo/functions/python27/invocations/ api localdemo/python3 was registered url: http://localhost:8000/2016-08-15/services/localdemo/functions/python3/invocations/ api localdemo/nodejs6 was registered url: http://localhost:8000/2016-08-15/services/localdemo/functions/nodejs6/invocations/ api localdemo/nodejs8 was registered url: http://localhost:8000/2016-08-15/services/localdemo/functions/nodejs8/invocations/ api localdemo/java8 was registered url: http://localhost:8000/2016-08-15/services/localdemo/functions/java8/invocations/ function compute app listening on port 8000!
Run the following command to install Function Compute SDK for Python:pip install aliyun-fc2
Enter the following code:import fc2 client = fc2.Client(endpoint='http://localhost:8000', accessKeyID='<your access key id>', accessKeySecret='your access key secret') resp = client.invoke_function('localdemo', 'php72') print resp.headers print resp.data
Note The AccessKey ID and AccessKey secret configured in the SDK code must be the same as those in Funcraft. Otherwise, signature authentication fails when you invoke functions.The following figure shows the running result.
Other operations
- Run the fun local invoke command to access a service on the host
If you use Docker 18.03 or later for macOS or Windows, you can use host.docker.internal as the IP address to access your on-premises service. For example, you can run the following command:
If you use a version earlier than Docker 18.03, you can run the ifconfig command for Linux or macOS or the ipconfig command for Windows on the host to view the host IP address and configure the IP address to the endpoint.client = fc2.Client(endpoint='http://host.docker.internal:8000', accessKeyID='xxx', accessKeySecret='xxx') resp = client.invoke_function('localdemo', 'nodejs8', json.dumps({'code': 123}))
- Use environment variables
Environment variables configured in the template.yml file are the same as those in Function Compute. You can run code to obtain the environment variables when functions are executed. For more information, see Configure environment variables.
You can determine whether a function is invoked on premises or in Function Compute based on the environment variables for specific logic processing.
- Credentials
You can use the AccessKey pair that is stored in credentials to access other Alibaba Cloud services. The fun local and fun deploy commands use the same method to search for the AccessKey pair.
For more information about Function Compute credentials, see the following sample code.
The following code provides an example on how to configure an OSS client by using credentials on premises and in Function Compute:local = bool(os.getenv('local', "")) if (local): print 'thank you for running function in local!!!!!!' auth = oss2.Auth(creds.access_key_id, creds.access_key_secret) else: auth = oss2.StsAuth(creds.access_key_id, creds.access_key_secret, creds.security_token)