BlackDog Foundry Bookmark This page

ServeUp is a Mac OS X application that can be used by iOS and Android developers to serve mock responses to iOS or Android applications.

The problem ServeUp solves

Almost every mobile app developer has to fetch (or update) data from a remote server via remote APIs. The mobile app under development is tightly coupled to a) the existence of these remote APIs, b) the stability/reliability of the APIs, and c) the types of data that is returned from the APIs.

Unavailability/unreliability of APIs leads directly to a significant loss in developer productivity. Insufficient test data being returned from the APIs also reduces overall product quality (for example, it is difficult to test how the app reacts to various response codes and data conditions).

The proposed solution

ServeUp is a Mac OS X app that offers the ability to serve static and dynamic responses to mobile apps based on inbound requests. Typical usage of ServeUp would look something like:

  • Identify the APIs that need to be mocked
  • Capture (or create) sample responses for each API
  • Configure ServeUp so that it maps inbound requests to responses
  • Configure mobile app to point to ServeUp as API server (eg. http://localhost:8080)

The mapping between a request and a response is called a route. ServeUp supports sophisticated pattern matching techniques to determine which response should be served back to the phone for each request. At the most basic level of use, ServeUp might have a one-to-one mapping between an inbound URL and a response file. For example, for a mobile app that calls some user-based APIs:

/api/v1/listUsers might return the contents of a file called users.json /api/v1/saveUser might return the contents of a file called saved.json

When ServeUp receives an inbound network request it iterates through the routes until it finds one that matches the incoming request. That route definition then describes what response should be sent back to the caller.

Routes

Why should you use ServeUp?

ServeUp offers the following advantages over other mechanisms for mocking responses:

  • An intuitive UI that makes it easy to make changes
  • Changes can be made quickly, and are effective immediately, without the need to stop, recompile the app, and resume again
  • ServeUp responses are able to easily be shared between iOS and Android apps

Matching inbound requests

Everytime an incoming request is received by ServeUp, it iterates through the list of routes to find one that matches the values in the incoming request.

The following attributes can be interrogated to determine whather the incoming request matches each route. The following section describes each of the matchable attributes.

Match

The route also contains some informational notes that can be used to provide info about type of request that the route is trying to match.

And lastly, a route can be disabled which removes it from the list of routes that get evaluated.

HTTP Method

A route specifies the expected HTTP method. For example, GET, POST, PUT, et al.

URL

A route can also match on a specific URL. Note that the values are compared against the fully specified URL (eg. http://localhost:8080/a/b/c/d?foo=bar#somefragment) including hostname, port number, query parameters, and fragments.

The possible matching options are:

  • Any – This will match any URL
  • Equals – Matches if the provided value exactly matches the fully specified inbound URL.
  • Not Equals – Matches if the provided value for not match the fully specified URL.
  • Contains – Matches if the provided value is contained within the fully specified URL. This is the most common scenario.
  • Regular Expression – Matches if the provided regular expression matches the fully specified URL.

Query String

A route can attempt to match on parameters contained in the query string. For example, the above screenshot is looking for a URL that contains a query parameter of foo that equals bar. For example, http://x.x.x.x/blah?foo=bar.

HTTP Header

A route can attempt to match on HTTP headers such as Authorization, or Accept-Encoding. In the example above, it is looking for an authorization token with a value of abcd.

Cookies

A route can also match on the value of inbound cookies. Technically speaking, a cookie comes in as a HTTP header (so it could be matched there), however, ServeUp will parse the cookies and match on the individual cookie values.

Form Variables

Some requests contains encoded form variables in the HTTP body (eg. field1=somevalue&field2=123. ServeUp allows a route to specify that it must match on the value of a specific form variable.

JSON Variables

Similarly, many requests contain a JSON payload in the HTTP body. ServeUp supports a KVO/Xpath-like parsing syntax to extract values from the inbound JSON. For example, consider the case where the HTTP body contains:

{
  "name": "John", 
  "pets": [
    {
      "name": "Pluto"
    }, 
    {
      "name": "Sylvester"
    }
  ], 
  "addresses": [
    {
      "type" : "home",
      "address": {
        "number": 123,
        "street": "Smith St"
      }
    },
    {
      "type" : "work",
      "address": {
        "number": 47,
        "street": "Jones Rd"
      }
    }
  ]
}

The following simple syntaxes are supported:

  • name => John
  • pets[0].name => Pluto
  • pets[1].name => Sylvester
  • addresses[0].type => home
  • addresses[0].address.number => 123
  • addresses[1].type => work
  • addresses[1].address.street => Jones Rd

Returning responses

Once a route has been matched, ServeUp then determines which response it should send back.

There are three main types of responses that can be returned:

  • Empty response. Simply returns a status code, and no body.
  • Static text. Returns some text that is entered in the ServeUp UI, along with a corresponding mime type. This would normally only be used for small responses.
  • File. Reads the contents of a file and returns it to the caller. This is the most commonly used response type.

Response

Status code

The HTTP status code that will be returned. Often this is 200, but not always.

File name

For file-based responses, this field defines the name of the file that is read and its contents returned.

It can be an absolute path (eg. /Users/sally/users.json) or a relative path (eg. users.json, ./users.json, responses/users.json). By default, relative paths are resolved in relation to the location of the currently loaded ServeUp configuration. For example, if your your ServeUp configuration file is located at /Users/sally/someproject/config.serveup, then by default the document root for the files will be /Users/sally/someproject. This can be overridden in the settings for each ServeUp project.

ServeUp determines the mime type for the response data based on the extension of the input file. eg. a file called blah.json will use application/json.

If the file specified in this field is not able to be found, by default, ServeUp will return a 404 error.

Fall through if not found

As mentioned above, if the file specified in the File name field doesn’t exist on the file system, ServeUp will normally return a 404 error.

This Fall through if not found flag allows that behaviour to be overridden. If the file is not found and this flag is enabled, ServeUp will treat this route as unmatched and move on to evaluate the next route in the list.

Where this is particularly useful is if you want to provide a specific response for a some requests, but a default response for other similar requests. For example, imagine you are providing responses for an app that uses URLs like /api/user/123456 where 123456 is the user name. Often, you want to be able to provide a specific response for user 123456, but are happy for all other users to receive the same default response.

In this case, you would create two routes (the order is important):

  • Regex Matching /api/user/(.*) that returns user_{{match.0}}.json with Fall through if not found checked
  • Matching /api/user that returns user_default.json

The first route uses Variable Substitution to be able to look for a specific file for every user. If there isn’t a file for the specific user, then ServeUp will fall through, match the second route, and return the default response.

Delay

If enabled, ServeUp will delay the response for a random number of milliseconds between the start and end range values.

By default, there is no delay.

Drop connection (not implemented yet)

This feature accepts the inbound connection, but instead of returning a response, just drops the connection.

A good use case for this is to simulate a user losing their network connection.

Reply with inbound cookies

This flag controls whether ServeUp will send back the same cookies as it receives.

Apply variable substitution

By default, ServeUp will apply variable substitution to the response body. However, if ServeUp is returning binary data (such as images), then this behaviour is not desirable. This flag stops the variable substitution on the response body from occuring (note that it will still perform variable substitution on any other fields that support it).

HTTP Headers

You can return specific HTTP headers as part of the response.

Cookies

Cookies can also be returned as part of the response.

Global overrides

As described above, each response handler has a number of attributes that can control its behaviour. However, there are some settings that can be applied at a global level to override the specific handler settings.

Global

In the example above, all responses would delay for somewhere between 2 and 3 seconds and return a 404 status code.

Variable substitution

ServeUp supports variable substitution in the response data for all fields (eg. HTTP body, HTTP Headers, Cookies, File name) using the Mustache syntax. An example of this is {{cookie.JSESSIONID}}. This would replace everything between the {{ and }} inclusively with the value of the JSESSIONID cookie.

The available variables are described below. By way of example, consider the following inbound request:

https://john:secret@www.myhost.com/api/user/1234?aaa=bbb&ccc=ddd#xyz
  Accept-Encoding: application/json
  Cookie: JSESSIONID=abcd
 
  { "name" : "Samantha", "pets" : [ "Rex", "Fido ] }

that matches the following URL matcher:

/api/user/(.*)?aaa=(.*)&.*

URL variables

  • docroot – The document root path (ie. where to find your files)
  • url – The full URL
  • scheme – The scheme of the URL => https
  • user – The user of the URL => john
  • password – The password of the URL => secret
  • host – The hostname that the request came to => www.myhost.com
  • port – The port that the request came to => 443
  • path – The path => /api/user/1234
  • query – Everything after the question mark => aaa=bbb&ccc=ddd
  • fragment – Everything after the hash => xyz

Request variables

  • parameter.NAME.X – The value of the X’th query string parameter for NAME. eg. {{parameter.aaa.0}} => bbb
  • match.X – The regular expression group of the URL matcher. eg. {{match.0}} => 1234, {{match.1}} => bbb
  • cookie.NAME – The value of cookie NAME. eg {{cookie.JSESSIONID}} => abcd
  • header.NAME – The value of HTTP header NAME. eg {{header.Accept-Encoding}} => application/json
  • form.NAME.X – The value of the X’th HTTP URL encoded form variable NAME. Not applicable in the above example as is not using form variables.
  • json.NAME – The value of a JSON element using NAME to extract the value. eg. json.name => Samantha, json.pets[1] => Fido. See JSON Variables section above for details on the supported syntax.

Calculated variables

  • randomTiny – Generates a random int between 1 and 9. eg {{randomTiny}} might return 6
  • randomSmall – Generates a random int between 1 and 99
  • randomMedium – Generates a random int between 1 and 999
  • randomLarge – Generates a random int between 1 and 999,999
  • randomCurrency – Generates a random float between 1.0 and 999.9

Settings

Port number

You can also control the port number (default 8080) that ServeUp listens on, and whether it automatically starts listening when ServeUp starts.

Use SSL

Based on the value of this flag, ServeUp will start the web server using a built-in self-signed SSL certificate.

If your mobile app does certificate-pinning or other SSL validations, you may need to mark this certificate as trusted. The easiest way to do this is to use a web browser on your mobile device to connect to ServeUp and follow the prompts to trust the certificate.

Auto-start

ServeUp can automatically start listening when a particular ServeUp configuration file is opened.

Document root

And lastly, you can control where ServeUp will look for files for the file-based response handler. By default, this is set to ., which means it is relative to the directory that the configuration .serveup file exists in.

Request History

ServeUp keeps a simple in-memory history of requests / responses that have recently been received. By selecting a request in the list, you can see the data that was received along with the data that was sent back to the caller.

Clicking on the icon in the list of the list will display a list of how each route was matched (or not) against the incoming request. In the example below, you can see exactly why the incoming request /api/v3/accounts matched each route.

History match test

Sharing between teams

One of the primary use cases that ServeUp has been designed for is to be able to share responses between team members whether they be developing iOS or Android apps.

One common way to achieve this is to configure ServeUp in the following way (let’s assume you are creating responses for an app called Blah):

  • Create a folder called Blah_ServeUp (it doesn’t really matter where, or what it is called)
  • Create a folder called Blah_ServeUp/responses
  • Open ServeUp and create a new configuration called Blah.serveup and save it in the Blah_ServeUp folder
  • In the settings for your configuration, set the document root to ./responses
  • Place all of your response files into Blah_ServeUp/responses
  • When you create routes with file-based handlers, you can now just set the file name to xxx.json and ServeUp will automatically pick them up from the Blah/responses folder.
  • Commit, and push the Blah folder as a project to github or bitbucket.
  • Team members can now clone the project into whatever folder they like, and because all the paths are relative inside ServeUp everything will still work.

Download

Feel free to download a free trial of the application and provide feedback to support@serveupapp.com or via twitter.

Categories

Copyright © 2012 BlackDog Foundry