You can find many more advanced examples and real-life use cases using Serverless products in our Serverless Examples repository.
Code examples for Serverless Functions
This page shows examples of functions in Python, Node, Golang, PHP, and Rust that can be used in your Serverless Functions projects.
Before you startLink to this anchor
To complete the actions presented below, you must have:
- A Scaleway account logged into the console
- Owner status or IAM permissions allowing you to perform actions in the intended Organization
- A Serverless Functions namespace
- A text editor/IDE (such as
vi
or Visual Studio Code) - Knowledge of how to package your functions and their dependencies
PythonLink to this anchor
Returning a function result in PythonLink to this anchor
There are several ways to return a response from a handler function:
Response object with HTTP information:
def handle(event, context):return {"body": {"message": "hello world"},"statusCode": 200,"headers": {"Content-Type": ["application/json"],"your-header": "your-value"}}
Straight response without body:
def handle(event, context):return {"message": "hello world"}# orreturn "my Message"
Stringified response body (AWS Lambda):
import jsondef handle(event, context):return {"body": json.dumps({"message": "hello world"}),"headers": {"Content-Type": ["application/json"],},"statusCode": 200,}
Getting data in PythonLink to this anchor
Using environment variables
Python runtime includes the os
, which enables you to access the environment variables you define in your namespaces or functions.
The following snippet returns the environment variable ENV
you specified in the function or namespace configuration:
import osdef handle(event, context):env_variable = os.getenv('ENV')return env_variable
Using event objects in PythonLink to this anchor
You can pass information through your HTTP request with event objects. They are composed of the following objects:
path
: str - Parameters defined in the path of the HTTP requestqueryStringParameters
: dict[str, str] - Query Strings parameters of the HTTP requestbody
: str - Body of the HTTP request, you will have to parse it in your handler to use it properly.headers
: dict[str, str] - HTTP request headersmethod
: string - HTTP method usedisBase64Encoded
: boolean - Whether the request body is base64 encoded.
def handle(event, context):# the event object is a Python dictquery_param = event['queryStringParameters']['parameter']query_body = event['body']# ...
Example of reading URL parameters:
curl https://myfunc/user/?id=1
Will fill the event with the following parameters:
event['path'] = "/user/"event['queryStringParameters'] = {"id": "1"}
Using data from CRON jobs in PythonLink to this anchor
CRON jobs share the same pattern as HTTP calls. You can find the information passed into the CRON body in the event object:
def handle(event, context):cron_body = event['body']# ...
Connecting to HTTP services in PythonLink to this anchor
You might need to get information or transmit data to an external service. The Scaleway Python runtime includes the urllib
library which enables you to connect to HTTP services without adding external libraries.
Refer to our guide on code packaging if you want to use requests.
GET
request example
from urllib import request, parse, errorimport osauth_token=os.getenv('X-AUTH-TOKEN') # You can pass tokens through os environment variable or secret environment variableurl={YOUR URL} # If you want a dynamic URL based on information sent to handle(), define the URL inside the functiondef handle(event, context):req = request.Request(url, method='GET')req.add_header('X-Auth-Token',auth_token)try:res = request.urlopen(req).read().decode()except error.HTTPError as e:res = e.read().decode()return {"body": json.loads(res),"headers": {"Content-Type": ["application/json"],},"statusCode": 200,}
POST
request example
from urllib import request, parse, errorimport osauth_token=os.getenv('X-AUTH-TOKEN') # You can pass tokens through os environment variable or secret environment variableurl={YOUR URL} # If you want a dynamic URL based on information sent to handle(), please define the URL inside the functiondef handle(event, context):data=json.dumps({"sample_key": "sample_value"}).encode('ascii')req = request.Request(url, data=data, method="POST")req.add_header('Content-Type', 'application/json')req.add_header('X-Auth-Token', auth_token)# Sending request to Instance APItry:res=request.urlopen(req).read().decode()except error.HTTPError as e:res=e.read().decode()return {"body": json.loads(res),"headers": {"Content-Type": ["application/json"],},"statusCode": 200,}try:res = request.urlopen(req).read().decode()except error.HTTPError as e:res = e.read().decode()return {"body": json.loads(res),"headers": {"Content-Type": ["application/json"],},"statusCode": 200,}
To use other libraries like request
, you need to upload your project with advanced methods (recommended)
or use a ZIP file.
Advanced Python examplesLink to this anchor
To find advanced and real-world examples for Serverless Functions, take a look at our dedicated repository.
NodeLink to this anchor
Returning a function result in NodeLink to this anchor
The following examples use CommonJS modules. If you use ES modules, refer to the dedicated section of this documentation.
There are multiple ways a response can return from a handler function:
- With body and statusCode. This response type sets the status code as
HTTP Response Code
, and body as the response’s body, headers asHeaders
.
Stringified body (like AWS Lambda
):
module.exports.myHandler = (event, context, callback) => {return {statusCode: 201,body: JSON.stringify({message: "async function",}),headers: {"Content-Type": "application/json",},}}
Not Stringified body (like AWS Lambda
):
module.exports.myHandler = (event, context, callback) => {return {statusCode: 201,body: {message: "async function",},headers: {"Content-Type": "application/json",},}}
- With object/entity (number, boolean, string…) without properties body and statusCode
module.exports.myHandler = (event, context, callback) => {return {body: "message",headers: {"Content-Type": ["text/plain"],},};// Orreturn JSON.stringify({ message: "message" });// ORreturn "Hello, world";// ORreturn 1; // true, false, undefined, null...};
Using the callback parameter:
module.exports.myHandler = (event, context, callback) => {const response = {statusCode: 201,body: {message: "async function",},headers: {"Content-Type": "application/json",},};// Successful responsecallback(undefined, response);// Error responsecallback(new Error("something bad happened..."));};
- With a
Promise
:
module.exports.myHandler = async (event, context, callback) => {return {statusCode: 201,body: {message: "async function",},headers: {"Content-Type": "application/json",},};}// ORmodule.exports.myHandler = (event, context, callback) => {const response = {statusCode: 201,body: {message: "async function",},headers: {"Content-Type": "application/json",},};return new Promise((resolve, reject) => {// do somethingif (err) return reject(err);return resolve(response);});};
Using environment variables in NodeLink to this anchor
If you need to pass information to your function you can use environment variables defined at the namespace or function level. In JavaScript, they are stored in the process.env
object:
module.exports.myHandler = (event, context, callback) => {const myParameter = process.env.MYPARAMETER;return {statusCode: 201,body: JSON.stringify({parameter: myParameter,}),headers: {"Content-Type": "application/json",},}}
Using event componentsLink to this anchor
You can pass information through your HTTP request with the event object. It is composed of the following objects:
path
: string - Parameters defined in the path of the HTTP requestqueryStringParameters
: object - Query Strings parameters of the HTTP requestbody
: string - Body of the HTTP request, you will have to parse it in your handler to use it properlyheaders
: object - HTTP request headershttpMethod
: string - HTTP method usedisBase64Encoded
: boolean - Whether the request body is base64 encoded.
module.exports.myHandler = (event, context, callback) => {const queryStringParameters = event.queryStringParameters;const body = event.body;// ...};
Example of reading URL parameters:
curl https://myfunc/user/?id=1
Will fill the event with the following parameters:
event.path = "/user/"event.queryStringParameters = {"id": "1"}
Using data from CRON jobs in NodeLink to this anchor
CRON jobs share the same pattern as HTTP calls. You will find the information passed into the CRON body in the event object:
module.exports.myHandler = (event, context, callback) => {body = event.body;return {statusCode: 201,body: JSON.stringify({body: body,}),headers: {"Content-Type": "application/json",},};};
Connecting to HTTP services in NodeLink to this anchor
You might need to get information or transmit data to an external service. The following code snippets can be executed directly in Serverless Functions without adding external libraries.
Refer to our guide on code packaging, if you want to use fetch
, axios
, …
GET
request sample:
const https = require("https");exports.handle = async function (event, context) {let dataString = "";const response = await new Promise((resolve, reject) => {const req = https.get("https://pokeapi.co/api/v2/pokemon/ditto",function (res) {res.on("data", (chunk) => {dataString += chunk;});res.on("end", () => {resolve({statusCode: 200,headers: { "Content-Type": ["application/json"] },body: JSON.stringify(JSON.parse(dataString), null, 4),});});});req.on("error", (e) => {reject({statusCode: 500,body: "Something went wrong!",});});});return response;};
POST
request sample
const https = require("https");exports.handle = async function (event, context) {let dataString = "";const postData = JSON.stringify({name: "John Doe",email: "jdoe@scaleway.com",});const options = {hostname: "postman-echo.com",path: "/post",method: "POST",headers: {"Content-Type": "application/json",},};const response = await new Promise((resolve, reject) => {const req = https.request(options, (res) => {res.on("data", (chunk) => {dataString += chunk;});res.on("end", () => {resolve({statusCode: 200,headers: { "Content-Type": ["application/json"] },body: JSON.stringify(JSON.parse(dataString), null, 4),});});res.on("error", (e) => {reject({statusCode: 500,body: "Something went wrong!",});});});// write data to request bodyreq.write(postData);req.end();});return response;};
Using ES ModulesLink to this anchor
Node has two module systems: CommonJS
modules and ECMAScript
(ES
) modules. By default, Node treats your code files as CommonJS modules, however ES modules are also available on Scaleway Serverless Functions. ES modules give you a more modern way to reuse your code.
According to the official documentation, you can specify the module type in package.json
to use ES modules, as in the following example:
..."type": "module",...
This then enables you to write your code for ES modules:
export { handle };function handle(event, context, cb) {return {body: process.version,headers: { "Content-Type": ["text/plain"] },statusCode: 200,};}
The use of ES modules is encouraged, since they are more efficient and make setup and debugging much easier.
Using "type": "module"
or "type": "commonjs"
in your package.json file will enable/disable some features in Node runtime. For a comprehensive list of differences, refer to the official documentation, the following is a summary only:
commonjs
is used as default valuecommonjs
allows you to userequire/module.exports
(synchronous code loading that copies all file contents)module
allows you to useimport/export
ES6 instructions (optimized asynchronous loading that imports only the pieces of code you need)
Advanced Node.js examplesLink to this anchor
Check out our dedicated examples repository for advanced examples and real-life use cases using Serverless products.
GoLink to this anchor
- your code must be a valid Go module: a
go.mod
file is expected in the root directory (ex:go mod init myhandler
) - handler function must be in a file at the root of your module
- handler must be exported:
Handle
is correct, buthandle
is not because it is not exported - handler must have the following signature:
func HandlerName(w http.ResponseWriter, r *http.Request)
- handler cannot be in the
main
package
Suggested layout:
.├── go.mod # your go.mod defines your module├── go.sum # not always necessary├── myfunc.go # your exported handler must be defined here└── subpackage # you can have subpackages└── hello.go # with files inside
Hello world in GoLink to this anchor
package myfuncimport ("encoding/json""net/http")// Handle - Handle eventfunc Handle(w http.ResponseWriter, r *http.Request) {response := map[string]interface{}{"message": "We're all good","healthy": true,"number": 4,}responseB, err := json.Marshal(response)if err != nil {w.WriteHeader(http.StatusInternalServerError)return}w.Header().Set("Content-Type", "application/json")_, _ = w.Write(responseB)}
Using r *http.Request
object, you can get the method, the headers, the body, etc, as if you were using a simple http server.
You must use the w http.ResponseWriter
parameter to send a response to the function caller.
Using environment variables in GoLink to this anchor
You can use environment variables defined at the Namespace or Function level to pass information to your function:
In the following code snippet, we use environment variables to get Database configuration information:
package myfuncimport ("fmt""log""os")func Handle(w http.ResponseWriter, r *http.Request) {// For example, get Database configuration from environment variablesdbName := os.Getenv("DB_NAME")dbUser := os.Getenv("DB_USER")dbPassword := os.Getenv("DB_PASSWORD")dbHost := os.Getenv("DB_HOST")dbPort := os.Getenv("DB_PORT")connectionString := fmt.Sprintf("%s:%s@%s:%s/%s", dbUser, dbPassword, dbHost, dbPort, dbName)// Your code to use the database...// Technically it's not recommended to add database connections or other resource initialization// in function handler because it will be called each time a function is triggered.}
Read request contentLink to this anchor
Using net/http/httputil
can help to dump request content.
package myfuncimport ("fmt""net/http""net/http/httputil")// Handle - Handle eventfunc Handle(w http.ResponseWriter, r *http.Request) {dump, _ := httputil.DumpRequest(r, true)fmt.Fprintf(w, "%s\n", string(dump))}
Read URL Parameters in GoLink to this anchor
package myfuncimport ("encoding/json""net/http")// This handler will dump all URL parameters.func Handle(w http.ResponseWriter, r *http.Request) {res, _ := json.Marshal(r.URL)w.Write(res)}
Example of reading URL parameters:
curl https://myfunc/user/?id=1
Will fill the event with the following parameters:
r.URL.Path = "/user/"r.URL.RawQuery = "id=1"
Connecting to HTTP services in GoLink to this anchor
GET
request example
package myfuncimport ("io""net/http")func Handle(w http.ResponseWriter, r *http.Request) {req, err := http.Get("https://jsonplaceholder.typicode.com/posts")if err != nil {w.WriteHeader(http.StatusInternalServerError)return}body, err := io.ReadAll(r.Body)if err != nil {w.WriteHeader(http.StatusInternalServerError)return}w.Write([]byte(body))}
Testing your Go function locallyLink to this anchor
Local development makes it easier to write, test, and debug, as well as making it faster to call your function.
You can find our Go library here.
Advanced Go examplesLink to this anchor
Check out our dedicated examples repository for advanced examples and real-life use cases using Serverless products.
RustLink to this anchor
Hello world in RustLink to this anchor
use axum::{body::Body, extract::Request, response::Response,};use http::StatusCode;pub async fn handle(_req: Request<Body>) -> Response<Body> {Response::builder().status(StatusCode::OK).header("Content-type", "text/plain").body(Body::from("Hello from rust")).unwrap()}
Advanced Rust examplesLink to this anchor
Check our dedicated examples repository for advanced examples and real-life use cases using Serverless products.
PHPLink to this anchor
PHP runtime supports composer dependency management.
Adding composer.json
in your project will automatically fetch the required dependencies.
Returning a function result in PHPLink to this anchor
Response object with HTTP information:
<?phpfunction handle($event, $context){return ["body" => "Hello from php","statusCode" => 200,];}
Getting data in PHPLink to this anchor
Using environment variables
PHP runtime includes the getenv
function, which enables you to access the environment variables you define in your namespaces or functions.
The following snippet returns the environment variable ENV
you specified in the function or namespace configuration:
<?phpfunction handle($event, $context){$env = getenv("ENV");return ["body" => $env,"statusCode" => 200,];}
Using event objects in PHPLink to this anchor
You can pass information through your HTTP request with event objects. They are composed of the following objects:
path
: string - Parameters defined in the path of the HTTP requestqueryStringParameters
: map(string)string - Query Strings parameters of the HTTP requestbody
: string - Body of the HTTP request, you will have to parse it in your handler to use it properly.headers
: map(string)string - HTTP request headersmethod
: string - HTTP method usedisBase64Encoded
: boolean - Whether the request body is base64 encoded.
<?phpfunction handle($event, $context) {$queryparameter = $event["queryStringParameters"]["parameter"];$querybody = $event["body"];return ["body" => $querybody,"statusCode" => 200,];}
Example of reading URL parameters:
curl https://myfunc/user/?id=1
Will fill the event with the following parameters:
$event['path'] = "/user/"$event['queryStringParameters'] = {"id": "1"}
Using data from CRON jobs in PHPLink to this anchor
CRON jobs share the same pattern as HTTP calls. You can find the information passed into the CRON body in the event object:
<?phpfunction handle($event, $context) {$cronbody = $event["body"];return ["body" => $cronbody,"statusCode" => 200,];}
Advanced PHP examplesLink to this anchor
Check our dedicated examples repository for advanced examples and real-life use cases using Serverless products.