Blog

ColdBox 6.6.0 Released

Luis Majano February 04, 2022

Spread the word

Luis Majano

February 04, 2022

Spread the word


Share your thoughts

 

Today we are incredibly excited to release ColdBox v6.6.0 and its standalone companion libraries: CacheBox, LogBox and WireBox. This release has taken quite a few months and tons of years of research to complete. We have finally made WireBox a Hierarchical Dependency Injection framework. This is our first huge step into allowing multi-dependency management in ColdBox Modules. This means that you will be able to have modules of different versions running within the same ColdBox app and each module will be able to get the right dependency that it needs. With that said, let's explore this release.

update coldbox

# If you are using standalone libraries, then update those
update wirebox
update cachebox
update logbox

You can find our what's new document here: https://coldbox.ortusbooks.com/intro/release-history/whats-new-with-6.6.0. So let's explore the release notes.

Major Updates

API Resourceful Routes

We have created a shortcut approach to creating RESTFul API resources in your ColdBox Routers via the new method apiResources(). This method will create all the routes for your API service with no HTML views.

apiResources( "users" );
apiResources( "photos" );
VerbRouteEventPurpose
GET/photosphotos.indexGet all photos
POST/photosphotos.createCreate a photo
GET/photos/:idphotos.showShow a photo by id
PUT/PATCH/photos/:idphotos.updateUpdate a photo by id
DELETE/photos/:idphotos.deleteDelete a photo by id

Module Enhancements

We have made several enhancements with modules:

  • Performance optimizations when registering and activating modules
  • Modules now track their own registration and activation load times (Which are now visible in cbdebugger)
  • Better logging of modules when they activate and register

Experimental New App Structure

We have been working on a new directory structure for ColdBox applications where the web root is not just dumped with everything on it. We have made several internal tickets to allow for this to work and we have a very early alpha available in github: https://github.com/coldbox-templates/modern

Scheduler and Task Updates

There are so many tickets that helped resolved issues with the ColdBox schedulers and scheduled tasks. We have also solidifying our Adobe scope issues and brought many new helpers for developers when building task objects.

Integration Testing of Subdomain/Domain Routing

If you are building multi-tenant applications with ColdBox and are leveraging domain and subdomain routing, then you can easily use the domain argument in all of our request(), execute() and HTTP Verb methods to simulate the domain in play for THAT specific spec execution.


describe( "subdomain routing", function(){
	beforeEach( function(){
		setup();
	} );
	
	it( "can match on a specific domain", function(){
		var event = execute( route: "/", domain: "subdomain-routing.dev" );
		var rc    = event.getCollection();
		expect( rc ).toHaveKey( "event" );
		expect( rc.event ).toBe( "subdomain.index" );
	} );
	
	it( "skips if the domain is not matched", function(){
		var event = execute( route: "/", domain: "not-the-correct-domain.dev" );
		var rc    = event.getCollection();
		expect( rc ).toHaveKey( "event" );
		expect( rc.event ).toBe( "main.index" );
	} );
	
	it( "can match on a domain with wildcards", function(){
		var event = execute( route: "/", domain: "luis.forgebox.dev" );
		var rc    = event.getCollection();
		expect( rc ).toHaveKey( "event" );
		expect( rc.event ).toBe( "subdomain.show" );
	} );
	
	it( "provides any matched values in the domain in the rc", function(){
		var event = execute( route: "/", domain: "luis.forgebox.dev" );
		var rc    = event.getCollection();
		expect( rc ).toHaveKey( "username" );
		expect( rc.username ).toBe( "luis" );
	} );
} );

Custom Session Identifiers

ColdBox has always had its internal way of figuring out what identifier to use for each user's request based on the way ColdFusion works. However, now you can influence and provide your own approach instead of relying on the core CFML approach. You will do this by adding a coldbox.identifierProvider closure/lambda into your config/Coldbox.cfc.

coldbox : {
    identifierProvider : function(){
        if( isNull( cookie.mytracker ) ){
            cookie.myTracker = createUUID();
        }
        return cookie.myTracker;
    }
}

WireBox Child Injectors

Welcome to the world of hierarchical dependency injection. We had the ability before to add a parent injector to WireBox, but now you can not only add a parent, but also many children to the hierarchy.

Every injector has the capability to store an ordered collection (ordered struct) of child injectors via the childInjectors property. Child injectors are used internally in many instances to provide a hierarchical approach to DI where instances can be searched for locally, in the parent and in the children. Here are some of the new methods to assist with child injectors:

  • hasChildInjector( name ) - Verify if a child injector has been registered
  • registerChildInjector( name, child ) - Register a child injector by name
  • removeChildInjector( name ) - Remove a child injector by name
  • getChildInjector( name ) - Get a child injector by name
  • getChildInjectors() - Get all the child injectors registered
  • getChildInjectorNames() - Get an array of all the registered child injectors

Child Enhanced Methods

  • getInstance()
    • The getInstance()method now has an injector argument so you can EXPLICITLY request an instance from a child injector by name getInstance( name : "service", injector : "childInjector" )
    • Apart from the explicit lookup it can also do implicit hierarchical lookups using the following order:
      • Locally
      • Parent
      • All Children (in order of registration)
  • containsInstance( name ) - This method now also searches in the child collection for the specific name instance. The lookup searches in the following order:
    1. Locally
    2. Parent
    3. Children
  • shutdown() - The shutdown method has been enhanced to issue shutdown method calls to all child injectors registered.

Getting Instances From Specific Child Injectors

The getInstance() has been modified to have an injector argument that you can use to specifically ask for an instance from that child injector. If the child injector has not been registered you will get a InvalidChildInjector Exception.

getInstance( name: "CategoryService", injector : "ChildInjector" )

Child Injector Explicit DSL

The following is the DSL you can use to explicitly target a child injector for a dependency. You will prefix it with wirebox:child: {name} and the name of the injector:

// Use the property name as the instance name
property name="categoryService" inject="wirebox:child:    childInjector"
// Use a specific instance name
property name="categoryService" inject="wirebox:child:    childInjector:CategoryService"
// Use any DSL
property name="categoryService" inject="wirebox:child:    childInjector:{DSL}"

IInjector Interface Updates

The coldbox.system.ioc.IInjector interface's getInstance() method has been modified to include support for child injector retrievals:

/**
 * Locates, Creates, Injects and Configures an object model instance
 *
 * @name The mapping name or CFC instance path to try to build up
 * @initArguments The constructor structure of arguments to passthrough when initializing the instance
 * @dsl The dsl string to use to retrieve the instance model object, mutually exclusive with 'name'
 * @targetObject The object requesting the dependency, usually only used by DSL lookups
 * @injector The child injector name to use when retrieving the instance
 */
function getInstance(
	name,
	struct initArguments,
	dsl,
	targetObject = "",
	injector
);

Release Notes

Bug

  • COLDBOX-1072 Non config apps fails since the core Settings.cfc had the configure() method removed
  • COLDBOX-1069 Framework Initialization Fails in @be on AutoWire of App Scheduler
  • COLDBOX-1066 Scheduled tasks not accessing application scope on Adobe Engines
  • COLDBOX-1063 ColdBox schedulers starting before the application is ready to serve requests
  • COLDBOX-1062 Scheduler service not registering schedulers with the appropriate name
  • COLDBOX-1051 scheduler names can only be used once - executor needs to be removed
  • COLDBOX-1036 Scheduled tasks fail after upgrading to coldbox 6.5. Downgrading to 6.4.0 works.
  • COLDBOX-1027 actions for a specific pattern cannot point to different handlers

Improvement

  • COLDBOX-1074 Improvements to module loading/activation log messages
  • COLDBOX-1071 Make unloadAll() in ModuleService more resilient by verifying loaded modules exist
  • COLDBOX-1061 Change default template cache from concurrentSoftReference to ConcurrentReference to avoid auto cleanups
  • COLDBOX-1056 Default route names to pattern when using route()
  • COLDBOX-1050 New router method: apiResources() to allow you to define resources without the new and edit actions
  • COLDBOX-1049 Update elixirPath to allow for many permutations of filenames and arguments to avoid cache collisions
  • COLDBOX-1048 Ability for the response setPagination() to use any incoming argument for storage
  • COLDBOX-1037 Move onRequestCapture after default event capture to allow for consistency on the capture
  • COLDBOX-980 Deprecate declaration of multiple resources on a single resources() call
  • COLDBOX-676 Improve routing DSL to allow for different HTTP verbs on the the same route to point to different events or actions

New Feature

  • COLDBOX-1082 Announce onException interception points for async interceptors
  • COLDBOX-1080 experimental web mapping support to allow for modern app templates with assets outside of the webroot
  • COLDBOX-1076 Ability to pass in the domain to test executions in via integration testing
  • COLDBOX-1073 Enable automated full null support via github actions
  • COLDBOX-1065 ScheduledTask new getMemento() to get the state of the task
  • COLDBOX-1064 Schedulers can now get the current thread and thread name: getCurrentThread(), getThreadName() as private helpers
  • COLDBOX-1033 New controller method: getUserSessionIdentifier() which gives you the unique request tracking identifier according to our algorithms
  • COLDBOX-1032 New coldbox setting identifierProvider which can be a closure/udf/lambda that provides a unique tracking identifier for user requests

Bug

  • CACHEBOX-76 Fixed method return value + SQL compatibility on jdbc metadata indexer thanks to @homestar9
  • CACHEBOX-75 reap operation was not ignoring 0 values for last access timeouts
  • CACHEBOX-74 Typo in queryExecute Attribute "datasource" in the JDBCStore.cfc

Improvement

  • CACHEBOX-73 Replace IIF and urlEncodedFormat on cache content reports
  • CACHEBOX-79 Lower logging verbosity of cache reaping from info to debug messages

Bug

  • WIREBOX-124 Killing IInjector interface usages due to many issues across cfml engines, leaving them for docs only
  • WIREBOX-118 Never override an existing variables key with virtual inheritance

Improvement

  • WIREBOX-120 DSLs process method now receives the caller targetID alongside the targetObject and the target definition

New Feature

  • WIREBOX-122 New wirebox DSL to inject the target's metadata that's cached in the target's binder: wirebox:objectMetadata
  • WIREBOX-121 New WireBoxDSL: wirebox:targetID to give you back the target ID used when injecting the object
  • WIREBOX-119 Missing coldbox:schedulerService DSL
  • WIREBOX-117 HDI - Ability for injectors to have a collection of child injectors to delegate lookups to, basically Hierarchical DI

Task

  • WIREBOX-123 Removal of usage of Injector dsl interface due to so many issues with multiple engines

Add Your Comment

Recent Entries

Live Stream Series - Koding with the Kiwi + Friends - July 1st 2022 Recap

Live Stream Series - Koding with the Kiwi + Friends - July 1st 2022 Recap

In our last session, Daniel and Gavin worked through a lot of content, what is the OpenAPI and Swagger Doc, some tools like editor.swagger.io and Daniel's CBSwaggerUI module. They looked at how to add tags, security, parameters, requestbody, responses and got side tracked down a really interesting rabbit hole after a question from one of the Patreons. Find out more and how to watch last weeks stream.

Gavin Pickin
Gavin Pickin
July 05, 2022
Ortus Content Digest for week of July 1st

Ortus Content Digest for week of July 1st

What has Ortus been publishing this week? We have the CFML News Podcast, more ITB Workshop Podcasts, some CFCasts and YouTube Videos, lots of Ortus and ITB Blog Posts. We have a lot more planned for next week as well

Gavin Pickin
Gavin Pickin
July 01, 2022