Since working with Ruby, I have been inspired to improve my coldfusion practices. While using Sinatra, I enjoyed being able to specify HTTP methods while mapping routes. In the same flavor, I wanted to write something for Mach-II that would allow me to do something similar. I wrote a Mach-II filter to accomplish this.
<cfcomponent display="RESTfulFilter" extends="MachII.framework.EventFilter">
<cffunction name="filterEvent" returnType="boolean">
<cfargument name="event" type="MachII.framework.Event" required="true" />
<cfargument name="eventContext" type="MachII.framework.EventContext" required="true" />
<cfargument name="paramArgs" type="struct" required="false" default="#StructNew()#" />
<cfset var requestMethod = cgi.REQUEST_METHOD />
<cfset var _method = arguments.event.getArg("_method", requestMethod) />
<cfset var restMethod = "" />
<cfif LCase(requestMethod) eq "get">
<cfset restMethod = "get" />
<cfelseif LCase(_method) eq "put">
<cfset restMethod = "put" />
<cfelseif LCase(_method) eq "delete">
<cfset restMethod = "delete" />
<cfelse>
<cfset restMethod = "post" />
</cfif>
<cfif StructKeyExists(paramArgs, restMethod)>
<cfset announceEvent(paramArgs[restMethod], arguments.event.getArgs()) />
<cfelse>
<cfthrow message="No event specified for REST method '#restMethod#'" />
</cfif>
<cfreturn false />
</cffunction>
</cfcomponent>A sample configuration is shown below. Each HTTP method specified in the parameters is essentially enabled and announces the specified event. If there is no event specified for the reqest HTTP method, then the request will error out.
<mach-ii version="1.5">
<event-filters>
<event-filter name="RESTfulFilter" type="model.RESTfulFilter" />
</event-filters>
<event-handlers>
<event-handler event="contact">
<filter name="RESTfulFilter">
<parameter name="get" value="contact.form" />
<parameter name="post" value="contact.action" />
</filter>
</event-handler>
<event-handler event="contact.form" access="private">
<event-arg name="contentPieceMappingName" value="contact" />
<notify listener="ContentListener" method="getContentPiece" />
<event-arg name="theme" value="white" />
<notify listener="ReCaptchaListener" method="getReCaptcha" resultArg="reCaptcha" />
<view-page name="contact" contentArg="content" />
<execute subroutine="layout.default" />
</event-handler>
<event-handler event="contact.action" access="private">
<notify listener="ReCaptchaListener" method="eventArgValidation" resultArg="reCaptchaValid" />
<event-bean name="Contact" type="model.Contact" />
<filter name="FormValidator">
<parameter name="formObjectName" value="Contact" />
<parameter name="invalidEvent" value="contact.form" />
</filter>
<notify listener="ContactListener" method="addContact" />
<event-arg name="contactsent" value="1" />
<redirect event="contact" args="contactsent" />
</event-handler>
</event-handlers>
</mach-ii>