docs: function registerRoute( namespace, restBase, options = {} ) {
  	// Support all methods until requested to do otherwise
  	let supportedMethods = [ 'head', 'get', 'patch', 'put', 'post', 'delete' ];
  
  	if ( Array.isArray( options.methods ) ) {
  		// Permit supported methods to be specified as an array
  		supportedMethods = options.methods.map( method => method.trim().toLowerCase() );
  	} else if ( typeof options.methods === 'string' ) {
  		// Permit a supported method to be specified as a string
  		supportedMethods = [ options.methods.trim().toLowerCase() ];
  	}
  
  	// Ensure that if GET is supported, then HEAD is as well, and vice-versa
  	if ( supportedMethods.indexOf( 'get' ) !== -1 && supportedMethods.indexOf( 'head' ) === -1 ) {
  		supportedMethods.push( 'head' );
  	} else if ( supportedMethods.indexOf( 'head' ) !== -1 && supportedMethods.indexOf( 'get' ) === -1 ) {
  		supportedMethods.push( 'get' );
  	}
  
  	const fullRoute = namespace
  		// Route should always have preceding slash
  		.replace( /^[\s/]*/, '/' )
  		// Route should always be joined to namespace with a single slash
  		.replace( /[\s/]*$/, '/' ) + restBase.replace( /^[\s/]*/, '' );
  
  	const routeObj = {};
  	routeObj[ fullRoute ] = {
  		namespace: namespace,
  		methods: supportedMethods,
  	};
  
  	// Go through the same steps used to bootstrap the client to parse the
  	// provided route out into a handler request method
  	const routeTree = buildRouteTree( routeObj );
  	// Parse the mock route object into endpoint factories
  	const endpointFactories = generateEndpointFactories( routeTree )[ namespace ];
  	const EndpointRequest = endpointFactories[ Object.keys( endpointFactories )[ 0 ] ].Ctor;
  
  	if ( options && options.params ) {
  		options.params.forEach( ( param ) => {
  			// Only accept string parameters
  			if ( typeof param !== 'string' ) {
  				return;
  			}
  
  			// If the parameter can be mapped to a mixin, apply that mixin
  			if ( typeof mixins[ param ] === 'object' ) {
  				Object.keys( mixins[ param ] ).forEach( ( key ) => {
  					applyMixin( EndpointRequest.prototype, key, mixins[ param ][ key ] );
  				} );
  				return;
  			}
  
  			// Attempt to create a simple setter for any parameters for which
  			// we do not already have a custom mixin
  			applyMixin( EndpointRequest.prototype, param, paramSetter( param ) );
  		} );
  	}
  
  	// Set any explicitly-provided object mixins
  	if ( options && typeof options.mixins === 'object' ) {
  
  		// Set any specified mixin functions on the response
  		Object.keys( options.mixins ).forEach( ( key ) => {
  			applyMixin( EndpointRequest.prototype, key, options.mixins[ key ] );
  		} );
  	}
  
  	function endpointFactory( options = {} ) {
  		return new EndpointRequest( {
  			...options,
  			...( this ? this._options : {} ),
  		} );
  	}
  	endpointFactory.Ctor = EndpointRequest;
  
  	return endpointFactory;
  }