toJSON no longer results in an infinite loop, returns simple objects

This commit is an attempt to solve issue #1011 where instead of succeeding or throwing, `JSON.stringify(request)` and `JSON.stringify(resp)` can cause infinite loops. This solution involves returning much smaller objects without any circular references so that serialization is possible.

The purpose of this PR is to look for feedback & keep the conversation going on whether this is a direction we want to go.

##### Context / Thinking (taken from #1011): 
> ... when the unknowing user serializes the object (intentionally and unintentionally) would they rather the default behavior be to throw an error, or successfully serialize only the basic properties?

> I definitely see the value in throwing and letting the user handle it every time, but this also means that every user will need to go into the object and find out what fields they need themselves. I imagine it's much more likely for the general user not to care, and maybe even prefer to have it extract only the basic, most valuable info. Also, if an expert user didn't like our simple serializer, they could just remove it (either through an option we provide or manually via `delete r.toJSON`).

##### Open Questions
1. Are there any other crucial properties? I just chose the few that seemed important
2. Do we want to keep `json-stringify-safe` for serializing a json body object? I'm not sure if we'd actually want to allow complex objects / objects with circular dependencies to be submitted via request, since they aren't really valid JSON. It might be helpful for users to remove this dependency/functionality for 3.0
3. Is this considered a breaking change? In some cases it didn't infinite loop, so for those cases it definitely is one.

===
/cc @mikeal @netpoetica
Is this here because JSON.stringify(obj) is not recursive at all?