BoxLang 🚀 A New JVM Dynamic Language Learn More...

Boxlang RESTful Services Compatibility Module

v1.0.0-snapshot BoxLang Modules

BoxLang REST Compatibility Module

A comprehensive CFML RESTful services compatibility module for BoxLang that provides compatibility for the CFML REST specification including routing, serialization, and OpenAPI documentation generation.

Overview

This module provides CFML-compatible REST services for BoxLang web applications, supporting:

  • RESTful Service Discovery & Registration: Automatic discovery and registration of REST-enabled CFCs
  • Intelligent Routing: Path-based routing with support for path parameters, query strings, and HTTP method matching
  • Content Negotiation: Automatic serialization/deserialization based on Accept and Content-Type headers
  • OpenAPI Documentation: Auto-generated OpenAPI 3.0 documentation for all registered services
  • CF-Compatible BIFs: restInitApplication, restSetResponse, restDeleteApplication
  • Multiple HTTP Methods: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
  • Rich Annotations Support: All standard CF REST annotations including httpMethod, produces, consumes, restPath, restArgSource

Installation

Add a servlet pass predicate which will match your default entry prefix in the web section of your server.json

"web":{
	"servletPassPredicate":"regex( '^/(.+?\\.cf[cms])(/.*)?$' ) or regex( '^/(.+?\\.bx[sm])(/.*)?$' ) or path-prefix-nocase( /rest/ )",
	...
}

Add a web.xml override to your server.json to allow the servlet to pass REST routes to BoxLang

Place the following in a file ( for example .rest-override.xml )

<web-app>
  <servlet-mapping>
	<servlet-name>BoxLangServlet</servlet-name>
	<url-pattern>rest/*</url-pattern>
  </servlet-mapping>
</web-app>

Then update your server.json to point to your override file.

"app" : {
	"webXMLOverride" : "./.rest-override.xml",
	...
}

Update your server file to install the module on your initial server start

.server.json scripts block:

"scripts" : {
	"onServerInitialInstall" : "install bx-plus,bx-compat-rest"
}

Start your server and go

Configuration

The following configuration items are supported and can be configured in the modules block of your boxlang.json or .cfconfig.json file:

"bx-compat-rest":{
	"settings":{
		// The entry prefix to use for all rest applications
		"entryPrefix" : "/rest/",
		// A struct containing the service name and fully expanded route to the directory containing the REST classes
		"applications":{
			// Key-value pairs
			"api":"/home/resty/my/rest/api/classes",
			// Key with struct to specify default application
			"resty" : {
				"path" : "/home/resty/my/rest/defaultAPI",
				"default" : true
			}
		}
	}
}

Quick Start

1. Create a REST-Enabled Component

// HelloService.bx
component rest="true" restPath="hello" {
    
    remote string function sayHello() httpMethod="GET" produces="application/json" {
        return "Hello, World!";
    }
    
    remote string function sayHelloTo(
        required string name restArgSource="Path"
    ) httpMethod="GET" restPath="{name}" produces="application/json" {
        return "Hello, #arguments.name#!";
    }
}

2. Register Your REST Application

In your Application.cfc:

component {
    this.name = "MyRESTApp";
    
    // Register REST application on startup
    function onApplicationStart() {
        restInitApplication(
            expandPath("./services"),  // Directory containing REST CFCs
            "api"                       // Service mapping name
        );
    }
}

3. Access Your REST Endpoints

GET  /rest/api/hello
GET  /rest/api/hello/John

Built-in Functions (BIFs)

restInitApplication()

Registers a REST application directory.

restInitApplication(
    rootPath,      // Required: Directory containing REST CFCs
    serviceName,   // Optional: Service name/mapping
    options        // Optional: Struct with host, useHost, isDefault
)

Example:

restInitApplication(expandPath("./api"), "myapi", {
    "host": "api.example.com",
    "isDefault": true
});

restSetResponse()

Sets a custom HTTP response with status, content, and headers.

restSetResponse({
    "status": 201,
    "content": {"id": 123, "message": "Created"},
    "headers": {"Location": "/api/resource/123"}
});

restDeleteApplication()

Removes a registered REST application.

restDeleteApplication("myapi");

OpenAPI Documentation

Access auto-generated OpenAPI 3.0 documentation:

GET /bxrest/public/RestController.bx?method=docs

The documentation includes:

  • All registered services and routes
  • HTTP methods and paths
  • Request parameters and their types
  • Response schemas
  • Content types (produces/consumes)

Advanced Features

Path Parameters

remote function getUser(
    required numeric id restArgSource="Path"
) httpMethod="GET" restPath="users/{id}" {
    return getUserById(arguments.id);
}

Access as: /api/users/123

Custom HTTP Status Codes

remote function createUser(
    required string name restArgSource="Form"
) httpMethod="POST" {
    var newUser = saveUser(arguments.name);
    
    restSetResponse({
        "status": 201,
        "content": newUser,
        "headers": {"Location": "/api/users/" & newUser.id}
    });
    
    return newUser;
}

Content Negotiation

The module automatically handles content negotiation based on:

  • Accept header for responses
  • Content-Type header for requests

Supported formats:

  • application/json, text/json
  • application/xml, text/xml
  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

Error Handling

remote function getUser(required numeric id restArgSource="Path") {
    if (!userExists(id)) {
		restSetResponse( 
			{
				"status" : 404,
				"content" : "User not found"
			}
		);
		return;
    }
    return getUser By(id);
}

The module automatically returns appropriate HTTP status codes:

  • 200 OK - Successful response with body
  • 204 No Content - Successful response without body
  • 400 Bad Request - Missing required parameters
  • 404 Not Found - No matching route
  • 405 Method Not Allowed - HTTP method not supported for route
  • 406 Not Acceptable - Cannot produce requested content type
  • 415 Unsupported Media Type - Cannot consume request content type
  • 500 Internal Server Error - Exception during processing

Compatibility

This module implements the ColdFusion RESTful services specification as documented in: https://helpx.adobe.com/coldfusion/developing-applications/changes-in-coldfusion/restful-web-services-in-coldfusion.html

Supported features:

  • ✅ REST component and function annotations
  • ✅ HTTP method binding
  • ✅ Path parameters and routing
  • ✅ Content negotiation
  • ✅ JSON and XML serialization
  • ✅ Custom responses
  • ✅ Parameter sources (Path, Query, Form, Header, Cookie, Body)
  • ✅ restInitApplication, restSetResponse, restDeleteApplication BIFs
  • ⚠️ Subresource locators (partial - basic implementation complete)
  • ⚠️ Custom serializers (not yet implemented)

Support


Ortus Solutions, Corp https://www.ortussolutions.com

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.


[Unreleased]

  • First iteration of this module

$ box install bx-compat-rest

No collaborators yet.
     
  • {{ getFullDate("2026-02-21T16:16:10Z") }}
  • {{ getFullDate("2026-04-14T22:51:21Z") }}
  • 226
  • 562