CFC Hints, Documentation, and Multiple Versions

38 views
Skip to first unread message

Daniel Short

unread,
May 10, 2016, 9:32:37 AM5/10/16
to Taffy Users
Hi all,

I'm creating a breaking change version of my API, and having problems with the dashboard and documentation outputting duplicate hints for methods that call SUPER.method(). Here is an example of what I'm doing:

/v1/Resources/types.cfc:

component extends="v2.Resources.Types" taffy_uri="/types/{type}" {

/**
* Returns various types needed for working with the LOA API.
* Valid types are 'sort', 'property', 'location', 'status',
* 'dt' (date values), 'listing'. Values are returned as an array
* of structures containing their ID and a text label. Below
* is an example of a request to /types/property<br /><br />
* <strong>Sample return value:</strong>
    * <br /><p class="label label-default responseStatus">200 OK</p>
* <pre><code>
* [
* <br />&nbsp;&nbsp;&nbsp;{
* <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"ID":&nbsp;1,
* <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"type":&nbsp;"Residential"
* <br />&nbsp;&nbsp;&nbsp;},
* <br />&nbsp;&nbsp;&nbsp;{
* <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"ID":&nbsp;2,
* <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"type":&nbsp;"Acreage"
* <br />&nbsp;&nbsp;&nbsp;},
* <br />&nbsp;&nbsp;&nbsp;{
* <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"ID":&nbsp;3,
* <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"type":&nbsp;"Acreage&nbsp;w/House"
* <br />&nbsp;&nbsp;&nbsp;},
* <br />&nbsp;&nbsp;&nbsp;...
* <br />]
* </code></pre>
*
* @output false
* @APIKey The API Key for your account. This value is required for all interactions with the API.
**/
public function GET(
required string APIKey
) taffy_mime="application/json" taffy_default="true" {

switch( Arguments.Type ) {
case "sort":
LOCAL.retVal = SUPER.getSorts();
break;

case "property":
LOCAL.retVal = getProperties();
break;

case "dt":
LOCAL.retVal = SUPER.getDTValues();
break;

case "status":
LOCAL.retVal = SUPER.getStatusValues();
break;

case "location":
LOCAL.retVal = SUPER.getLocationValues();
break;

case "listing":
LOCAL.retVal = SUPER.getListingValues();
break;

default:
return representationOf( { "errors": [ { "Invalid Type": "No valid type provided" } ] } ).withStatus( 400, "Bad Request" );
}

if( StructKeyExists( LOCAL, "retVal" ) AND IsQuery( LOCAL.retVal ) ) {
return representationOf( queryToArray( LOCAL.retVal ) ).withStatus( 200, "OK" );
} else {
return representationOf( LOCAL.retVal ).withStatus( 200, "OK" );
}

}

/**
* @hint Returns the list of valid property types for the application
* @output false
*/
private query function getProperties( ) {

LOCAL.search = Server.GW.Common.getStyles();

LOCAL.filteredSearch = New Query( sql = "
SELECT
         tableID AS ID,
        style AS type
   FROM sourceQuery
");
LOCAL.filteredSearch.setAttributes( sourceQuery = LOCAL.search );
LOCAL.filteredSearch.setDBType( "query" );
LOCAL.results = LOCAL.filteredSearch.Execute().getResult();

return LOCAL.results;

}

}

/v2/Resources/types.cfc:

component extends="taffy.core.resource" taffy_uri="/types/{type}" {

/**
* Returns various types needed for working with the LOA API.
* Valid types are 'sort', 'property', 'location', 'status',
* 'dt' (date values), 'listing'. Values are returned as an array
* of structures containing their ID and a text label. Below
* is an example of a request to <code>/types/property</code>. There may be other
* data included with the return values. For example, property types will include
* boolean values to distinguish between Land and Water types.<br /><br />
* <strong>Sample return value:</strong>
    * <br /><p class="label label-default responseStatus">200 OK</p>
* <pre><code>
* [
* <br />&nbsp;&nbsp;&nbsp;{
* <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"WaterType": 1,
* <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"ID": 1024,
* <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"LandType": 0,
* <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"type": "Beachfront"
* <br />&nbsp;&nbsp;&nbsp;},
* <br />&nbsp;&nbsp;&nbsp;{
* <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"WaterType": 0,
* <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"ID": 64,
* <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"LandType": 1,
* <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"type": "Commercial Land"
* <br />&nbsp;&nbsp;&nbsp;},
* <br />&nbsp;&nbsp;&nbsp;{
* <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"WaterType": 0,
* <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"ID": 1,
* <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"LandType": 1,
* <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"type": "Farms"
* <br />&nbsp;&nbsp;&nbsp;},...
* <br />]
* </code></pre>
*
* @output false
* @APIKey The API Key for your account. This value is required for all interactions with the API.
*/
public function GET(
required string APIKey
) taffy_mime="application/json" taffy_default="true" {

switch( Arguments.Type ) {
case "sort":
LOCAL.retVal = getSorts();
break;

case "property":
LOCAL.retVal = getProperties();
break;

case "dt":
LOCAL.retVal = getDTValues();
break;

case "status":
LOCAL.retVal = getStatusValues();
break;

case "location":
LOCAL.retVal = getLocationValues();
break;

case "listing":
LOCAL.retVal = getListingValues();
break;

default:
return representationOf( { "errors": [ { "Invalid Type": "No valid type provided" } ] } ).withStatus( 400, "Bad Request" );
}

if( StructKeyExists( LOCAL, "retVal" ) AND IsQuery( LOCAL.retVal ) ) {
return representationOf( queryToArray( LOCAL.retVal ) ).withStatus( 200, "OK" );
} else {
return representationOf( LOCAL.retVal ).withStatus( 200, "OK" );
}

}

/**
* @hint Returns the list of valid sort IDs for the application
* @output false
*/
private query function getSorts( ) {

LOCAL.search = Server.Utilities.Toolbox.getSortingQuery( hasPowerSearch = False );

LOCAL.filteredSearch = New Query( sql = "
SELECT
        id,
        display
   FROM sourceQuery
");
LOCAL.filteredSearch.setAttributes( sourceQuery = LOCAL.search );
LOCAL.filteredSearch.setDBType( "query" );
LOCAL.results = LOCAL.filteredSearch.Execute().getResult();

return LOCAL.results;

}

/**
* @hint Returns the list of valid property types for the application
* @output false
*/
private query function getProperties( ) {

LOCAL.search = Server.GW.Common.getPropertyTypes();

LOCAL.filteredSearch = New Query( sql = "
SELECT
        TypeID AS ID,
        Label AS type,
        LandType,
        WaterType
   FROM sourceQuery
");
LOCAL.filteredSearch.setAttributes( sourceQuery = LOCAL.search );
LOCAL.filteredSearch.setDBType( "query" );
LOCAL.results = LOCAL.filteredSearch.Execute().getResult();

return LOCAL.results;

}

/**
* @hint Returns all valid DT values for use against the listings resource.
* @output false
*/
private array function getDTValues() {

return [
{
"label": "Last 24 hours",
"ID": "Last24Hours"
},
{
"label": "Last 3 days",
"ID": "Last3Days"
},
{
"label": "Last week",
"ID": "LastWeek"
},
{
"label": "Last 2 weeks",
"ID": "Last2Weeks"
},
{
"label": "Last month",
"ID": "LastMonth"
},
{
"label": "Last 3 months",
"ID": "Last3Months"
},
{
"label": "Last year",
"ID": "LastYear"
}
];

}

/**
* @hint Returns all valid status values for use against the listings resource.
* @output false
*/
private array function getStatusValues() {

return [
{
"label": "Active",
"ID": "P"
},
{
"label": "Under Contract",
"ID": "PP"
},
{
"label": "Sold",
"ID": "PS"
},
{
"label": "Inactive",
"ID": "PI"
}
];

}

/**
* @hint Returns all valid location values for use against the listings resource.
* @output false
*/
private array function getLocationValues() {

return [
{
"label": "County",
"ID": "county"
},
{
"label": "State",
"ID": "state"
},
{
"label": "Lake",
"ID": "lake"
},
{
"label": "Region",
"ID": "region"
},
{
"label": "City",
"ID": "city"
}
];

}
/**
* @hint Returns all valid listing values for use against the listings resource.
* @output false
*/
private array function getListingValues() {

return [
{
"label": "Auctions",
"ID": "1"
},
{
"label": "For Sale",
"ID": "2"
}
];

}

}

When viewing the API documentation for v1 of the API, I'm seeing duplicate hints for the types resource (image attached).

Is this a known issue, and is there something I can do in the CFC code itself to prevent the duplicate output, or should I start digging into the dashboard code to figure out where the cause is?

Thanks,

Dan

apidocs.png

Daniel Short

unread,
May 10, 2016, 11:01:38 AM5/10/16
to Taffy Users
The following fix to getHintsFromMetaData in api.cfc has corrected the issue. I'll commit this as a pull request:

<cfif not structKeyExists(func, "access") or (func.access neq "private" and func.access neq "package")>
<!--- check to see if this function is already in the list. If so, overwrite, otherwise append --->
<cfset foundFunc = False />
<cfloop from="1" to="#arrayLen( result.functions )#" index="g">
<cfif result.functions[g].NAME EQ func.NAME>
<cfset result.functions[g] = func />
<cfset foundFunc = True />
<cfbreak />
</cfif>
</cfloop>
<cfif NOT foundFunc>
<cfset arrayAppend(result.functions, func) />
</cfif>
</cfif>



Adam Tuttle

unread,
May 10, 2016, 1:00:19 PM5/10/16
to Taffy Users
Thanks for the contribution, Dan!

Adam

--
You received this message because you are subscribed to the Google Groups "Taffy Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to taffy-users...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages