Velo: Exposing a Site API with HTTP Functions
Endpoints
- 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>
- You can test your HTTP Functions using Functional Testing. You do not have to publish your site before doing so.
- You must publish your site at least once before using both the testing and production endpoints. After that, you save your site for changes you make to testing endpoints to take effect and you publish your site for changes you make to the production endpoints to take effect.
Permissions
API Function Code
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 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()
.
get( )
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/Doe
6 let options = {
7 "headers": {
8 "Content-Type": "application/json"
9 }
10 };
11 // query a collection to find matching items
12 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 found
18 if(results.items.length > 0) {
19 options.body = {
20 "items": results.items
21 };
22 return ok(options);
23 }
24 // no matching items found
25 options.body = {
26 "error": `'${request.path[0]} ${request.path[1]}' was not found`
27 };
28 return notFound(options);
29 } )
30 // something went wrong
31 .catch( (error) => {
32 options.body = {
33 "error": error
34 };
35 return serverError(options);
36 } );
37}
post( )
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 body
11 return request.body.text()
12 .then( (body) => {
13 // insert the item in a collection
14 return wixData.insert("myUserCollection", JSON.parse(body));
15 } )
16 .then( (results) => {
17 options.body = {
18 "inserted": results
19 };
20 return created(options);
21 } )
22 // something went wrong
23 .catch( (error) => {
24 options.body = {
25 "error": error
26 };
27 return serverError(options);
28 } );
29}
30
put( )
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 body
11 return request.body.text()
12 .then( (body) => {
13 // update the item in a collection
14 return wixData.update("myUserCollection", JSON.parse(body));
15 } )
16 .then( (results) => {
17 options.body = {
18 "inserted": results
19 };
20 return ok(options);
21 } )
22 // something went wrong
23 .catch( (error) => {
24 options.body = {
25 "error": error
26 };
27 return serverError(options);
28 } );
29}
delete( )
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 collection
11 return wixData.remove("myUserCollection", request.path[1])
12 .then( (results) => {
13 options.body = {
14 "deleted": results
15 };
16 return ok(options);
17 } )
18 // something went wrong
19 .catch( (error) => {
20 options.body = {
21 "error": error
22 };
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.