What's "bad" about the request?
Giving a generic failure response isn't terribly useful to the poor soul who has to deal with handling the errors when interfacing with your API. Why did it fail? You're only catching the case where the response either is or isn't valid JSON, but what about other kinds of failure?
One thing you might want to look at is Digestive Functors, if you haven't already. You can use it to do some of your error handling (eg. the value for FieldB is out of the specified range, etc.). There's a Digestive Functors Aeson library that will let you send your JSON result through the form. I don't do much with passing around JSON data myself, so this might be a bit more than you need.
The database can fail, too
You've only handled the case where decoding your JSON request can fail, not the database portion. When it comes to the database, there are 4 basic outcomes to a query:
- Success: Results
- Success: No results
- Failure: Constraint Violations (errors caused by the user)
- Failure: SQL errors (errors caused by the developer)
So for queries that can fail (any time you run an insert/update/delete query), you'll want to make sure you're catching the Constraint Violations. PostgreSQL Simple has a convenient function in Database.PostgreSQL.Simple.Errors (catchViolation) specifically for that (though if you're using the PostgreSQL Simple snaplet rather than using PostgreSQL Simple directly, you'll have to roll your own because the type signatures are incompatible).
Snap Extras might be right for you
There's another package called snap-extras that contains useful functions like reading the response as JSON or responding with JSON. I know some people aren't too fond of it since it has a lot of dependencies, but I tend to use some of the other modules in it, so it's convenient for me.
If not, you can easily copy/paste just the parts you need into your own project.