LogoLogo
HomeAPIBlog
3.0.0-SNAPSHOT
3.0.0-SNAPSHOT
  • INTRODUCTION
    • Getting Started
      • Running Local Development Servers
      • Beginner Tutorial: Hello World
      • Beginner Tutorial: Hello Database
      • Tutorial: Wheels, AJAX, and You
    • Frameworks and Wheels
    • Requirements
    • Manual Installation
    • Upgrading
    • Screencasts
  • Command Line Tools
    • CLI Commands
    • wheels - commands
    • wheels generate - commands
    • wheels dbmigrate - commands
    • wheels plugins - commands
  • Working with Wheels
    • Conventions
    • Configuration and Defaults
    • Directory Structure
    • Switching Environments
    • Testing Your Application
    • Contributing to Wheels
    • Documenting your Code
  • Handling Requests with Controllers
    • Request Handling
    • Rendering Content
    • Redirecting Users
    • Sending Files
    • Sending Email
    • Responding with Multiple Formats
    • Using the Flash
    • Using Filters
    • Verification
    • Event Handlers
    • Routing
    • URL Rewriting
      • Apache
      • IIS
      • Tomcat
      • Nginx
    • Obfuscating URLs
    • Caching
    • Nesting Controllers
    • CORS Requests
  • Displaying Views to Users
    • Pages
    • Partials
    • Linking Pages
    • Layouts
    • Form Helpers and Showing Errors
    • Displaying Links for Pagination
    • Date, Media, and Text Helpers
    • Creating Custom View Helpers
    • Localization
  • Database Interaction Through Models
    • Object Relational Mapping
    • Creating Records
    • Reading Records
    • Updating Records
    • Deleting Records
    • Column Statistics
    • Dynamic Finders
    • Getting Paginated Data
    • Associations
    • Nested Properties
    • Object Validation
    • Object Callbacks
    • Calculated Properties
    • Transactions
    • Dirty Records
    • Soft Delete
    • Automatic Time Stamps
    • Database Migrations
      • Migrations in Production
    • Using Multiple Data Sources
  • Plugins
    • Installing and Using Plugins
    • Developing Plugins
    • Publishing Plugins
  • Project Documentation
    • Overview
  • External Links
    • Source Code
    • Issue Tracker
    • Sponsor Us
    • Community
Powered by GitBook
LogoLogo
On this page
  • Requesting Different Formats
  • Responding to Different Formats in the Controller
  • Providing the HTML Format
  • Automatic Generation of XML and JSON Formats
  • Providing Your Own Custom Responses

Was this helpful?

Edit on GitHub
Export as PDF
  1. Handling Requests with Controllers

Responding with Multiple Formats

Wheels controllers provide some powerful mechanisms for responding to requests for content in XML, JSON, and other formats. You can build an API with ease using these functions.

If you've ever needed to create an XML or JSON API for your Wheels application, you may have needed to go down the path of creating a separate controller or separate actions for the new format. This introduces the need to duplicate model calls or even break them out into a super long list of before filters. With this, your controllers can get pretty hairy pretty fast.

Using a few Wheels functions, you can easily respond to requests for HTML, XML, JSON, and PDF formats without adding unnecessary bloat to your controllers.

Requesting Different Formats

With Wheels Provides functionality in place, you can request different formats using the following methods:

  1. URL Variable

  2. URL Extension

  3. Request Header

Which formats you can request is determined by what you configure in the controller. See the section below on Responding to Different Formats in the &#xNAN;Controller for more details.

URL Variable

Wheels will accept a URL variable called format. If you wanted to request the XML version of an action, for example, your URL call would look something like this:

http://www.example.com/products?format=xml

The same would go for JSON:

http://www.example.com/products?format=json

URL Extension

Perhaps a cleaner way is to request the format as a "file" extension. Here are the XML and JSON examples, respectively:

http://www.example.com/products.xml
http://www.example.com/products.json

This works similarly to the URL variable approach mentioned above in that there will now be a key in the params struct set to the format requested. With the XML example, there will be a variable at params.format with a value of xml.

Request Header

If you are calling the Wheels application as a web service, you can also request a given format via the HTTP Accept header.

If you are consuming the service with another Wheels application, your <cfhttp> call would look something like this:

In this example, we are sending an Accept header with the value for the xml format.

<cfhttp url="http://www.example.com/products">
    <cfhttpparam type="header" name="Accept" value="application/octet-stream">
</cfhttp>
  • html

  • xml

  • json

  • csv

  • pdf

  • xls

addFormat(extension="doc", mimeType="application/msword");

Responding to Different Formats in the Controller

Take a look at this example:

component extends="Controller" {

  function config(){
    provides("html,json,xml");
  }

  function index(){
    products = model("product").findAll(order="title");
    renderWith(products);
  }
}

When Wheels handles this response, it will set the appropriate MIME type in the Content-Type HTTP header as well.

Providing the HTML Format

Automatic Generation of XML and JSON Formats

Best Practices for Providing JSON

Unfortunately there have been a lot of JSON related issues in CFML over the years. To avoid as many of these problems as possible we thought we'd outline some best practices for you to follow.

authors = model("author").findAll(returnAs="structs");

The reason for doing it this way is that it will preserve the case for the struct / JSON keys.

renderWith(data=authors, firstName="string", booksForSale="integer");

With that in place you can be sure that firstName will always be treated as a string (i.e. wrap in double quotes) and booksForSale as an integer (i.e. no decimal places) when producing the JSON output. Without this, your CFML engine might guess what the data type is, and it wouldn't always be correct unfortunately.

Providing Your Own Custom Responses

If you need to provide content for another type than xml or json, or if you need to customize what your Wheels application generates, you have that option.

In your controller's corresponding folder in app/views, all you need to do is implement a view file like so:

Type
Example

html

app/views/products/index.cfm

xml

app/views/products/index.xml.cfm

json

app/views/products/index.json.cfm

csv

app/views/products/index.csv.cfm

pdf

app/views/products/index.pdf.cfm

xls

app/views/products/index.xls.cfm

If you need to implement your own XML-based or JSON-based output, the presence of your new custom view file will override the automatic generation that Wheels normally performs.

Example: PDF Generation

If you need to provide a PDF version of the product catalog, the view file at app/views/products/index.pdf.cfm may look something like this:

HTML

<cfdocument format="pdf">
    <h1>Products</h1>
    <table>
        <thead>
            <tr>
                <th>Name</th>
                <th>Description</th>
                <th>Price</th>
            </tr>
        </thead>
        <tbody>
            #includePartial(products)#
        </tbody>
    </table>
</cfdocument>
PreviousSending EmailNextUsing the Flash

Last updated 21 days ago

Was this helpful?

Here is a list of values that you can grab from with Wheels out of the box.

You can use to set more types to the appropriate MIME type for reference. For example, we could set a Microsoft Word MIME type in app/config/settings.cfm like so:

The fastest way to get going with creating your new API and formats is to call from within your controller's config() method.

By calling the function in config(), you are instructing the Wheels controller to be ready to provide content in a number of formats. Possible choices to add to the list are html (which runs by default), xml, json, csv, pdf, and xls.

This is coupled with a call to in the following actions. In the example above, we are setting a query result of products and passing it to . By passing our data to this function, Wheels gives us the ability to respond to requests for different formats, and it even gives us the option to just let Wheels handle the generation of certain formats automatically.

You can also use the call in an individual controller action to define which formats the action will respond with. This can be used to define behavior in individual actions or to override the controller's config().

Responding to requests for the HTML version is the same as you're already used to with . will accept the same arguments as , and you create just a view template in the views folder like normal.

If the requested format is xml or json, the function will automatically transform the data that you provide it. If you're fine with what the function produces, then you're done!

First of all, always return data as an array of structs. This is done by using the returnAs argument (on for example), like this:

Secondly, make use of Wheels ability to return the JSON values in a specified type. This is done in the function, like this:

mimeTypes()
addFormat()
provides()
provides()
renderwith()
renderwith()
onlyProvides()
Rendering Content
renderwith()
renderView()
renderwith()
findAll()
renderWith()