My Dreamforce 2013 Developer Theater Presentation

Exposing Force.com RESTful Services using Swagger.

Try it live:
http://force-com-rest-swagger.herokuapp.com

Fork my project
https://github.com/thysmichels/force.com-swagger-rest-spring-mvc

Here are some photos from the event:

photo 1

photo 2

Presentation attached:
DF13_Exposing Salesforce REST Service using Swagger

Youtube video:

Force.com REST Swagger Spring MVC

Swagger is a specification and complete framework implementation for describing, producing, consuming, and visualizing RESTful web services. The overarching goal of Swagger is to enable client and documentation systems to update at the same pace as the server. The documentation of methods, parameters, and models are tightly integrated into the server code, allowing APIs to always stay in sync. With Swagger, deploying managing, and using powerful APIs has never been easier.

Spring Swagger Controller code

package com.thysmichels.swagger4forcedotcom.controllers;

import com.knappsack.swagger4springweb.controller.ApiDocumentationController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * This is an example of how you might extend the ApiDocumentationController in order to set your own RequestMapping
 * (instead of the default "/api") among other possibilities.  Going this route, you do not necessarily have to define
 * the controller in your servlet context.
 */
@Controller
@RequestMapping(value = "/api")
public class ExampleDocumentationController extends ApiDocumentationController {

    public ExampleDocumentationController() {
        setBaseControllerPackage("com.thysmichels.swagger4forcedotcom.controllers.api");
        setBaseModelPackage("com.thysmichels.swagger4forcedotcom.models");
        setApiVersion("v1");
    }

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String documentation() {
        return "api";
    }
}

Force.com REST Implementation Code

package com.thysmichels.swagger4forcedotcom.controllers.api;

import java.util.List;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
import javax.ws.rs.core.Response;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;


import com.force.api.ForceApi;
import com.force.api.QueryResult;
import com.thysmichels.swagger4forcedotcom.models.Account;
import com.thysmichels.swagger4forcedotcom.services.SalesforceLogin;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiError;
import com.wordnik.swagger.annotations.ApiErrors;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;

@Controller
@RequestMapping(value = "/api/v1/account")
@Api(value = "Account operations", listingClass = "AccountController", basePath = "/api/v1/account", description = "All operations for accounts")
public class AccountController {
	
	@Inject
	@Named("SalesforceLogin")
	private SalesforceLogin sfdcLogin;
	private ForceApi api;
	
	@PostConstruct
	public void init()
	{
		api = sfdcLogin.loginToSalesforce();
	}
	
	 @ApiOperation(value = "Find all accounts", notes = "Get all account currently available", httpMethod = "GET", responseClass = "Account", multiValueResponse = true)
	 @ApiError(code = 500, reason = "Process error")
	 @RequestMapping(value = "/", method = RequestMethod.GET, produces = "application/json")
	 public @ResponseBody List<Account> showAllAccounts() {
	    	QueryResult<Account> res = api.query("SELECT Name FROM Account", Account.class);
	        return res.getRecords();
	 }
	
	@ApiOperation(value = "Find account by Id", notes = "Get account by specifying Id", httpMethod = "GET", responseClass = "Account", multiValueResponse = true)
	@ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"), @ApiError(code = 404, reason = "Account not found") })
	@RequestMapping(value = "/{accountId}", method = RequestMethod.GET, produces = "application/json")
    public @ResponseBody Account[] findAccountById(@ApiParam(internalDescription = "java.lang.string", name = "accountId", required = true, value = "string") @PathVariable String accountId) {
    	Account account = api.getSObject("account", accountId).as(Account.class);
        return new Account[]{account};
    }

	
	@ApiOperation(value = "Delete a account", notes = "Delete a specific account with the given ID", httpMethod = "DELETE")
    @ApiError(code = 500, reason = "Process error")
    @RequestMapping(value = "/{accountId}", method = RequestMethod.DELETE, produces = "application/json")
    public @ResponseBody String deleteAccount(@ApiParam(internalDescription = "java.lang.string", name = "accountId", required = true, value = "string") @PathVariable String accountId) {
    	api.deleteSObject("account", accountId);
    	return "{status: success}";
    }
	
	@ApiOperation(value = "Create a account using Param", notes = "Creates a new account in salesforce using Param", httpMethod = "POST")
    @ApiError(code = 500, reason = "Process error")
    @RequestMapping(method = RequestMethod.POST, produces = "application/json")
    public @ResponseBody String createAccountFromParamName(@ApiParam(internalDescription = "java.lang.string", value="string", name = "Name", required = false) @RequestParam(required = true) String Name) 
    {	
		Account newAccount = new Account();
		newAccount.setName(Name);
    	String id = api.createSObject("Account", newAccount);
    	return "{id:" + id +"}";
    }
	
	@ApiOperation(value = "Create a account", notes = "Creates a new account in salesforce", httpMethod = "POST")
    @ApiError(code = 500, reason = "Process error")
    @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
    public @ResponseBody String createAccountFromJSON(@RequestBody Account newAccount) 
    {	
    	String id = api.createSObject("Account", newAccount);
    	return "{id:" + id +"}";
    }
	
	@ApiOperation(value = "Update Account", notes = "Update a existing Account", httpMethod = "POST") 
	@RequestMapping(value = "/{accountId}", method = RequestMethod.POST, consumes = "application/json")
	 public @ResponseBody String updateAccount(@PathVariable String accountId, @RequestBody Account account) {
		 api.updateSObject("Account", accountId, account);
		 return "{status: success}";
	 }
}

Screenshots

Salesforce Spring MVC Swagger

Salesforce Spring MVC Swagger1