Within the /api
directory of your projects, ZEIT Now will automatically recognize the languages listed on this page, through their file extensions, and serve them as Serverless Function.
Supported Languages:
Node.js
File Extensions: .js
, .ts
Default Runtime Version: 8.10.x (or defined)
Node.js files through a JavaScript file or a TypeScript file within the api
directory, containing a default exported function, will be served as a Serverless Function.
For example, the following would live in api/hello.js
:
module.exports = (req, res) => { const { name = 'World' } = req.query res.status(200).send(`Hello ${name}!`) }
Example deployment: https://node-api.now-examples.now.sh/api/hello?name=reader
Node.js TypeScript support:
Deploying a Node.js function with the .ts
extension will automatically be recognized as a TypeScript file and compiled to a Serverless Function.
As an example; a file called hello.ts
in the api
directory, and importing types for the ZEIT Now platform Request and Response objects from the @now/node
module:
import { NowRequest, NowResponse } from '@now/node' export default (request: NowRequest, response: NowResponse) => { const { name = 'World' } = request.query response.status(200).send(`Hello ${name}!`) }
Example deployment: https://ts-api.now-examples.now.sh/api/hello?name=reader
You can install the @now/node
module for type definitions through npm:
npm i -D @now/node
You can also define a tsconfig.json
to configure the ZEIT Now TypeScript compiler:
{ "compilerOptions": { "module": "commonjs", "target": "esnext", "sourceMap": true, "strict": true } }
Node.js Request and Response Objects
For each request of a Node.js Serverless Function, two objects, request and response, are passed to it. These objects are the standard HTTP request and response objects given and used by Node.js, but they include extended helpers provided by ZEIT Now:
Node.js Helpers
method | description | object |
---|---|---|
req.query | An object containing the request's query string, or {} if the request does not have a query string. | request |
req.cookies | An object containing the cookies sent by the request, or {} if the request contains no cookies. | request |
req.body | An object containing the body sent by the request, or null if no body is sent. | request |
res.status(code) | A function to set the status code sent with the response where code must be a valid HTTP status code. Returns res for chaining. | response |
res.send(body) | A function to set the content of the response where body can be a string , an object or a Buffer . | response |
res.json(obj) | A function to send a JSON response where obj is the JSON object to send. | response |
The following example showcases the use of req.query
, req.cookies
and req.body
helpers:
module.exports = (req, res) => { let who = 'anonymous' if (req.body && req.body.who) { who = req.body.who } else if (req.query.who) { who = req.query.who } else if (req.cookies.who) { who = req.cookies.who } res.status(200).send(`Hello ${who}!`) }
req.body
We populate the req.body
property on the request object with a parsed version of the content sent with the request when it is possible.
We follow a set of rules on the Content-type
header sent by the request to do so:
Content-Type header | Value of req.body |
---|---|
No header | undefined |
application/json | An object representing the parsed JSON sent by the request. |
application/x-www-form-urlencoded | An object representing the parsed data sent by with the request. |
text/plain | A string containing the text sent by the request. |
application/octet-stream | A Buffer containing the data sent by the request. |
With the req.body
helper, you can build applications without extra dependencies or having to parse the content of the request manually. The following example inspects req.body
, if it is 'ping', it will return 'pong'.
module.exports = (req, res) => { if (typeof req.body !== 'string') { return res.status(400).text('Invalid request') } if (req.body !== 'ping') { return res.status(400).text('The value expected is `ping`') } res.status(200).send('pong') }
Node.js Async Support
ZEIT Now supports asynchronous functions out-of-the-box.
In this example, we use the package asciify-image
to create ascii art from a person's avatar on GitHub. First, we need to install the package:
npm i --save asciify-image
In our code, we export an asynchronous function and we take advantage of the helpers.
const asciify = require('asciify-image') module.exports = async (req, res) => { if (!req.query.username) { return res.status(400).send('username is missing from query parameters') } const avatarUrl = `https://github.com/${req.query.username}.png` const opts = { fit: 'box', width: 40, height: 40 } const asciified = await asciify(avatarUrl, opts) return res.status(200).send(asciified) }
Node.js Dependency Installation
The installation of dependencies behaves as follows:
- If a
package-lock.json
is present,npm install
is used - Otherwise,
yarn
is used.
Defined Node.js Version
The Node.js version, though defaulted to 8.10.x, can be changed to 10.x by defining engines in package.json
:
{ "name": "my-app", "engines": { "node": "10.x" } }
Go
File Extension: .go
Default Runtime Version: Go 1.x
Go files in the api
directory that export a function matching the net/http
Go API will be served as a Serverless Function.
For example, the following would live in api/date.go
:
package handler import ( "fmt" "net/http" "time" ) func Handler(w http.ResponseWriter, r *http.Request) { currentTime := time.Now().Format(time.RFC850) fmt.Fprintf(w, currentTime) }
When deployed, the example function above will be served as a Serverless Function, returning the latest date. See it live with the following link: https://go-api.now-examples.now.sh/api/date
Private Packages for Go
To install private packages with go get
, define GIT_CREDENTIALS
as a build environment variable.
All major Git providers are supported including GitHub, GitLab, Bitbucket, as well as a self-hosted Git server.
With GitHub, you will need to create a personal token with permission to access your private repository.
{ "build": { "env": { "GIT_CREDENTIALS": "https://username:token@github.com" } } }
Go Build Configuration
You can provide custom build flags by using the GO_BUILD_FLAGS
build environment variable.
{ "build": { "env": { "GO_BUILD_FLAGS": "-ldflags '-s -w'" } } }
Python
File Extension: .py
Default Runtime Version: Python 3.6
Python files within the api
directory, containing an handler variable that inherits from the BaseHTTPRequestHandler
class or an app
variable that exposes a WSGI or ASGI application, will be served as a Serverless Function.
For example, the following would live in api/date.py
:
from http.server import BaseHTTPRequestHandler from datetime import datetime class handler(BaseHTTPRequestHandler): def do_GET(self): self.send_response(200) self.send_header('Content-type', 'text/plain') self.end_headers() self.wfile.write(str(datetime.now().strftime('%Y-%m-%d %H:%M:%S')).encode()) return
When deployed, the example function above will be served as a Serverless Function, returning the current date and time. See it live with the following link: https://python-api.now-examples.now.sh/api/date
Python Dependencies
ZEIT Now supports installing dependencies for Python defined in the requirements.txt
file or a Pipfile.lock
file at the root of the project.
Related
For more information on what to do next, we recommend the following articles: