Velo: Exposing a Site API with HTTP Functions
Using Velo you can create functions to expose the functionality of your site as a service. That means other people can use the functionality of your site by writing code that calls your site's API as defined by the Wix functions you create.
Important: The HTTP Functions API is only intended for use in server-to-server communications. If you use this API to set a cookie on a site visitor's browser you may no longer be in compliance with applicable data privacy regulations.
You might want to use HTTP functions to:
- Integrate your site with an automation tool, such as Zapier or IFTTT.
- Receive notifications and information from external webhooks.
- Share a backend between your site and a native mobile application.
Endpoints
Clients consume your HTTP functions by reaching endpoints using the following pattern:
- For premium sites:
https://www.{user\_domain}/\_functions/<functionName>
. - For free sites:
https://{user\_name}.wixsite.com/{site\_name}/\_functions/<functionName>
.
You can test your HTTP functions by reaching endpoints using the following pattern:
- For premium sites:
https://www.{user\_domain}/\_functions-dev/<functionName>
. - For free sites:
https://{user\_name}.wixsite.com/{site\_name}/\_functions-dev/<functionName>
.
Notes:
-
You can test your HTTP functions using Functional Testing. You do not have to publish your site before doing so.
-
When using Git Integration, you can test your code in the local editor or push your code to GitHub and run functional testing with the Wix code editor.
-
You must publish your site at least once before using either testing or production endpoints. After that, you can do the following:
- To make changes made to testing endpoints take effect, save your site.
- To make changes made to production endpoints take effect, publish your site.
Permissions
HTTP functions, no matter how they are invoked, always run with the permissions of an anonymous site visitor.
API Function Code
API function logic is defined in a file you create and name http-functions.js in your site's backend.
HTTP functions are defined using the following pattern:
1export function <prefix>_<functionName>(request) { }
where prefix
is one of get
, post
, put
, delete
, or use
.
Inside an HTTP function, you can write the logic to handle an incoming request and return an appropriate response. The function receives a WixHttpFunctionRequest
object that contains information about the incoming request. The function must return a WixHttpFunctionResponse
. There are a number of functions you can use to create the WixHttpFunctionResponse
, such as response()
, ok()
, created()
, notFound()
, serverError()
, badRequest()
, and forbidden()
.
See the API reference for Wix HTTP Functions for more information.
get( )
This function responds to requests made with the HTTP GET method. Usually, it is called by consumers to retrieve a resource and should have no other effect. If defined in this way and the resource is found, your function should respond with a 200 (OK) status code and the requested resource.
Example: Create a GET HTTP function that queries a collection to find items based on the path of the request.
1import {ok, notFound, serverError} from 'wix-http-functions';2import wixData from 'wix-data';3
4export function get_myFunction(request) {5 // URL looks like: https://www.mysite.com/_functions/myFunction/John/Doe6 let options = {7 "headers": {8 "Content-Type": "application/json"9 }10 };11 // query a collection to find matching items12 return wixData.query("myUserCollection")13 .eq("firstName", request.path[0])14 .eq("lastName", request.path[1])15 .find()16 .then( (results) => {17 // matching items were found18 if(results.items.length > 0) {19 options.body = {20 "items": results.items21 };22 return ok(options);23 }24 // no matching items found25 options.body = {26 "error": `'${request.path[0]} ${request.path[1]}' was not found`27 };28 return notFound(options);29 } )30 // something went wrong31 .catch( (error) => {32 options.body = {33 "error": error34 };35 return serverError(options);36 } );37}
post( )
This function responds to requests made with the HTTP POST method. Usually, it is called by consumers to create a new resource. If defined in this way and the resource is created, your function should respond with a 201 (Created) status code and usually a reference to the new resource.
Example: Create a POST HTTP function that inserts an item from the request's body into a collection.
1import {created, serverError} from 'wix-http-functions';2import wixData from 'wix-data';3
4export function post_myFunction(request) {5 let options = {6 "headers": {7 "Content-Type": "application/json"8 }9 };10 // get the request body11 return request.body.text()12 .then( (body) => {13 // insert the item in a collection14 return wixData.insert("myUserCollection", JSON.parse(body));15 } )16 .then( (results) => {17 options.body = {18 "inserted": results19 };20 return created(options);21 } )22 // something went wrong23 .catch( (error) => {24 options.body = {25 "error": error26 };27 return serverError(options);28 } );29}
put( )
This function responds to requests made with the HTTP PUT method. Usually, it is called by consumers to update an existing resource. If defined in this way and the resource is updated, your function should respond with a 200 (OK) status code. If defined in this way and the resource did is created because it did not exist, your function should respond with a 201 (Created) status code.
Example: Create a PUT HTTP function that updates an item from the request's body in a collection.
1import {ok, serverError} from 'wix-http-functions';2import wixData from 'wix-data';3
4export function put_myFunction(request) {5 let options = {6 "headers": {7 "Content-Type": "application/json"8 }9 };10 // get the request body11 return request.body.text()12 .then( (body) => {13 // update the item in a collection14 return wixData.update("myUserCollection", JSON.parse(body));15 } )16 .then( (results) => {17 options.body = {18 "inserted": results19 };20 return ok(options);21 } )22 // something went wrong23 .catch( (error) => {24 options.body = {25 "error": error26 };27 return serverError(options);28 } );29}
delete( )
This function responds to requests made with the HTTP DELETE method. Usually, it is called by consumers to delete an existing resource. If defined in this way and the resource is deleted, your function should respond with a 200 (OK) status code.
Example: Create a DELETE HTTP function that deletes an item from a collection based on the path of the request.
1import {ok, serverError} from 'wix-http-functions';2import wixData from 'wix-data';3
4export function delete_myFunction(request) {5 let options = {6 "headers": {7 "Content-Type": "application/json"8 }9 };10 // delete the item from a collection11 return wixData.remove("myUserCollection", request.path[1])12 .then( (results) => {13 options.body = {14 "deleted": results15 };16 return ok(options);17 } )18 // something went wrong19 .catch( (error) => {20 options.body = {21 "error": error22 };23 return serverError(options);24 } );25}
use( )
This function responds to requests made with any of the GET, POST, PUT, or DELETE HTTP methods unless another function is defined specifically for the request's HTTP method.
For example, if you create functions named get_myFunction
and use_myFunction
, GET calls to myFunction will be handled by get_myFunction
, while POST, PUT, and DELETE calls will be handled by use_myFunction
.
Debugging
You can debug HTTP functions by adding console.log()
calls to them.
The information you log appears in the function output when using Functional Testing and in your site's Logs.
The information logged by code that runs on the backend can also be viewed as Site Events. Site Events are accessible via Developer Tools > Logs on the site dashboard.