Skip to content

Commit

Permalink
feat(HyperBuilder): Allow registering a configured HyperRequest as a …
Browse files Browse the repository at this point in the history
…custom client

Instead of needing to know the init argument names to pass through,
a configured request can be registered directly with WireBox.
  • Loading branch information
elpete committed Jun 15, 2023
1 parent 5bf1260 commit 33348bc
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 3 deletions.
39 changes: 36 additions & 3 deletions models/HyperBuilder.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@ component singleton {
*
* @returns The new HyperBuilder instance.
*/
function init() {
this.defaults = new Hyper.models.HyperRequest();
public HyperBuilder function init( defaults = new Hyper.models.HyperRequest() ) {
this.defaults = arguments.defaults;
for ( var key in arguments ) {
if ( key == "defaults" ) {
continue;
}

invoke(
this.defaults,
"set#key#",
Expand All @@ -39,13 +43,42 @@ component singleton {
}
}

/**
* Registers a new custom Hyper client with the given request.
*
* @alias The WireBox mapping for the custom client.
* @defaults The request to use as the defaults for the custom client.
*
* @throws HyperNonColdBoxContext
* @returns The HyperRequest instance being used as the defaults.
*/
public HyperRequest function registerAs( required string alias, required HyperRequest defaults ) {
if ( !structKeyExists( variables, "wirebox" ) ) {
throw(
type = "HyperNonColdBoxContext",
message = "No wirebox instance available to register custom client. Are you sure you are running in a ColdBox context?"
);
}

variables.wirebox
.getBinder()
.forceMap( alias )
.to( "hyper.models.HyperBuilder" )
.asSingleton()
.initWith( defaults = arguments.defaults );

return arguments.defaults;
}

/**
* Create a new request from the default request.
*
* @returns A new HyperRequest instance from the default request.
*/
function new() {
return this.defaults.clone();
var req = this.defaults.clone();
req.setBuilder( this );
return req;
}

/**
Expand Down
15 changes: 15 additions & 0 deletions models/HyperRequest.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@ component accessors="true" {
*/
property name="responseCallbacks" type="array";

/**
* A reference to the HyperBuilder that created this request, if any.
*/
property name="builder" type="HyperBuilder";

/**
* Initialize a new HyperRequest.
*
Expand Down Expand Up @@ -1205,4 +1210,14 @@ component accessors="true" {
};
}

/**
* Registers this configured HyperRequest as the defaults for a named HyperBuilder in WireBox.
*
* @alias The name to register the custom HyperBuilder.
*
* @returns The HyperRequest instance.
*/
public HyperRequest function registerAs( required string alias ) {
return variables.builder.registerAs( alias, this );
}
}
4 changes: 4 additions & 0 deletions tests/resources/app/config/WireBox.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ component extends="coldbox.system.ioc.config.Binder" {
};

// Map Bindings below
map( "SWAPIClient" )
.to( "hyper.models.HyperBuilder" )
.asSingleton()
.initWith( baseUrl = "https://swapi.dev/api" );
}

}
27 changes: 27 additions & 0 deletions tests/specs/integration/BuilderDefaultsSpec.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,33 @@ component extends="tests.resources.ModuleIntegrationSpec" appMapping="/app" {
expect( req.getBaseUrl() ).toBe( "https://jsonplaceholder.typicode.com" );
expect( req.getHeader( "X-Requested-With" ) ).toBe( "XMLHTTPRequest" );
} );

it( "can configure builders in the WireBox config file", () => {
var hyper = getInstance( "SWAPIClient" );
var res = hyper.get( "/people/1" );
expect( res.isOK() ).toBeTrue();
var data = res.json();
expect( data ).toHaveKey( "name" );
expect( data.name ).toBe( "Luke Skywalker" );
} );

it( "can configure builders using a registerAs syntax", () => {
getInstance( "HyperBuilder@hyper" )
.setBaseUrl( "https://swapi.dev/api" )
.withRequestCallback( function( req ) {
req.withHeaders( { "X-Custom-Header" : "foobar" } );
} )
.registerAs( "SWAPIClient2" );

var hyper = getInstance( "SWAPIClient2" );
var res = hyper.get( "/people/1" );
expect( res.isOK() ).toBeTrue();
var data = res.json();
expect( data ).toHaveKey( "name" );
expect( data.name ).toBe( "Luke Skywalker" );
expect( res.getRequest().getHeaders() ).toHaveKey( "X-Custom-Header" );
expect( res.getRequest().getHeaders()[ "X-Custom-Header" ] ).toBe( "foobar" );
} );
} );
}

Expand Down

0 comments on commit 33348bc

Please sign in to comment.