data/source/handy_http_data/json.d

66 lines
2.3 KiB
D

/**
* Defines functions to read and write JSON values when handling HTTP requests.
*/
module handy_http_data.json;
import streams;
import handy_http_primitives.request;
import handy_http_primitives.response;
/**
* Reads a JSON value from the body of the given HTTP request, parsing it using
* the ASDF library according to the template type T.
*
* Throws a BAD_REQUEST HttpStatusException if deserialization fails.
* Params:
* request = The request to read the JSON from.
* Returns: The value that was read.
*/
T readJsonBodyAs(T)(ref ServerHttpRequest request) {
import asdf : deserialize, SerdeException;
try {
string requestBody = request.readBodyAsString(false);
return deserialize!T(requestBody);
} catch (SerdeException e) {
throw new HttpStatusException(HttpStatus.BAD_REQUEST, e.msg, e);
}
}
/**
* Writes a JSON value to the body of the given HTTP response, serializing it
* using the ASDF library. Will also set Content-Type and Content-Length
* headers before writing.
*
* Throws an INTERNAL_SERVER_ERROR HttpStatusException if serialization or
* writing fails.
* Params:
* response = The response to write to.
* bodyContent = The content to write.
*/
void writeJsonBody(T)(ref ServerHttpResponse response, in T bodyContent) {
import std.conv : to;
import std.traits : isArray;
import std.json;
import asdf : serializeToJson, SerdeException;
try {
static if (isArray!T && bodyContent.length == 0) {
string responseBody = "[]";
} else static if (is(T == JSONValue)) {
string responseBody = bodyContent.toString();
} else {
string responseBody = serializeToJson(bodyContent);
}
response.headers.remove("Content-Type");
response.headers.remove("Content-Length");
response.headers.add("Content-Type", "application/json");
response.headers.add("Content-Length", to!string(responseBody.length));
StreamResult result = response.outputStream.writeToStream(cast(ubyte[]) responseBody);
if (result.hasError) {
StreamError err = result.error;
throw new HttpStatusException(HttpStatus.INTERNAL_SERVER_ERROR, err.message);
}
} catch (SerdeException e) {
throw new HttpStatusException(HttpStatus.INTERNAL_SERVER_ERROR, e.msg, e);
}
}