Prism has had an abundance of new features since I first released it about a month ago.  This post discusses the rationale behind some of those features as well as a peak of what's next.

Prism is a library to record, mock, and proxy HTTP traffic.  Check out my previous post to learn more about its core functionality.  Also checkout the github repo's for connect-prism, grunt-connect-prism, and prism-sample-project.

New features:

gulp

Prism started out as a grunt plugin, but shortly after its début I started receiving requests for a gulp equivalent.  Not having much experience with gulp I investigated how to develop gulp plugins and eventually discovered their writing a plugin guidelines.  It's a really interesting read.  The gulp community is a lot more strict about what makes a good plugin than the grunt community.  Among various suggestions, requests, and outright demands, the number 1 requirement on their list is:

Your plugin should not do something that can be done easily with an existing node module.

If you're familiar with grunt this should strike a chord as there are thousands of grunt plugins that do nothing but wrap existing functionality of a core library.  Whether this was intended from grunt's beginnings or not, I'm not sure, but one positive that has come out of it is that it has opened the door for less nodejs savvy developers to use popular libraries within their grunt configuration.

The gulp community appears to pride itself on its succinctness of a deployment pipeline through their file streaming operations.  If your plugin isn't specifically integrating something else into the streaming pipline then it has no business being a plugin in the first place.

This inspired me to factor out the core functionality of grunt-connect-prism into a new simple to use core library called connect-prism.  I've updated my prism sample project to include an example of its usage within a gulpfile.js.

To use with gulp you simply add the prism middleware to your connect declaration and then instantiate 1 or more instances of prism.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
var prism = require('connect-prism');
var connect = require('connect');
 
var app = connect()
  .use(require('connect-livereload')({
    port: 35729
  }))
  .use(prism.middleware)
  .use(connect.static('app'))
  .use(connect.static('.tmp'))
  .use(
    '/bower_components',
    connect.static('./bower_components')
  )
  .use(connect.directory('app'));
 
require('http').createServer(app)
  .listen(9000)
  .on('listening', function() {
    console.log('Started connect web server on http://localhost:9000');
  });
 
prism.create({
  name: 'serve',
  mode: 'mock',
  context: '/api',
  host: 'localhost',
  port: 9090,
  delay: 'auto',
  rewrite: {
    '^/api/bookauthors': '/api/authors',
  }
});

delay

The delay option is 1 of 2 features contributed by Miloš Mošovský.  In many cases you probably want to use prism to eliminate latency of your API, but in some cases it's useful to see how your app behaves when it exists.  The delay option has several different options that let you generate this delay when you mock requests.

You can define a time in milliseconds or choose one of three modes that generates random delays within a range.  To learn more about how to configure this feature see the delay option section in the connect-prism README.

In the prism sample project I use the 'auto' mode of delay which will generate random delays between 500 and 1,750 milliseconds.  Below is a screenshot of the chrome debugger's network tab showing the 3 calls made to prism.

connect-prism-delay

404 stubbing

The second feature by Milos enables prism to generate stubs in your mocks directory when you're in mock mode (in record mode it would simply record a 404 response from your server).  If your API doesn't have an endpoint implemented then prism will create a hashed file like it normally does, but the file will have a .404 extension and will have an empty data property value.  If you choose to use the mock then customize the response data, status code, and content type (but NOT the request URL).  To use the mock just drop the .404 file extension so it's in the standard requestHash.json filename format.

If you keep an eye on the STDOUT you'll see that prism lets you know when it creates a 404 stub:

Serialized empty 404 response for /api/newendpoint to mocks/serve/d36d19f9d90fa6e1fc1755463d7c3a70616539af.json.404

This lets you know which file to inspect in your mocks directory:

1
2
3
4
5
seglo@bit:~/source/prism-sample-project$ ls mocks/serve/
0b956737b1a9660f2c555f9328db1191f6f2a050.json
2723f866830446c640c9cc9942fed2988e0a2c1a.json
6654ad4d1d494222ce02c656386e6955575c17ed.json
d36d19f9d90fa6e1fc1755463d7c3a70616539af.json.404

Default state of the .404 file.

1
2
3
4
5
6
{
  "requestUrl": "/api/newendpoint",
  "contentType": "application/javascript",
  "statusCode": 200,
  "data": {}
}

URL rewriting

This is your standard, run of the mill URL rewriting functionality. It was copied in wholesale from the grunt-connect-proxy plugin. When a request matches a context that prism is configured for then it will modify the request URL to the matched URL replacement.

This could be useful for rerouting many same requests to one mock. For example, since prism creates and matches mocks given a whole request URL, if you have query parameters they are included as part of the hash. To ignore all query parameters to /api/authors you could create a rewrite rule like the following.

1
2
3
rewrite: {
  '^/api/authors\??.*': '/api/authors'
}

Mock & Record mode

While in record you may not always record every request you intended to. If you miss a use case then while you're in mock mode it will simply return 404's (and create stubs as mentioned above) when there may well be a valid endpoint it could have used. I created a new mode you can run the plugin that combines both mocking and recording.

When prism intercepts a request it will first check if a mock response exists. If it does not, instead of the usual behaviour of stubbing out a response it will attempt to proxy & record the response from your actual server.

This is useful while developing if you've want to move to a new area of development (that triggers new requests) without switching to and from record mode.

It's also helpful to use during automated testing so you don't have to remember to record mocks every time new tests are added to your suite; the next test run will generate them and then subsequent test runs will use the mocks.

This mode can be used with the 'mockrecord' setting for the 'mock' property of the configuration. See the mode setting in the connect-prism README for more details.

What's next?

Runtime configuration override

This is a candidate feature request submitted by Myles Bostwick several days ago.  Myles proposed a feature where you could override the options of prism at run time with custom HTTP headers.  This would allow you to override options like the prism name to use (i.e. in VCR-speak, use another cassette) in order to test a different response.  This would be useful in test suites where you want to test how your app behaves under several different use cases, but not have to restart your test server or prism to do it.

Keep the suggestions coming

Since releasing this library it's been enhanced extensively through pull requests and suggestions from the community.  I'm not really sure where it's headed.  This is my first forray into open source worth mentioning and I'm thrilled by the feedback I'm receiving.