On 8/9/16 7:25 AM, Joseph Rushton Wakeling wrote:

Hello all,

I'm playing with the REST interface functionality of vibe.d and have got stuck on what seems like a simple problem: to create a POST request where the server returns back the data contained in the body of the POST request itself.

However, I always wind up with 400 Bad Request errors, with the claim that the request body does not contain a valid JSON value.

Here's my interface and implementation:

interface MyRestInterface
{
    string post (string data);
}

class MyRestImplementation : MyRestInterface
{
    string post (string data)
    {
        if (data is null) return "hello!";
        return data ~ data;
    }
}

and then in my main function:

auto myRestInterface = new MyRestImplementation;

auto router = new URLRouter;
registerRestInterface(router, myRestInterface);

auto settings = new HTTPServerSettings;
settings.port = httpPort;
settings.bindAddresses = ["::1", "127.0.0.1"];
listenHTTP(settings, router);

Sample behaviour when trying to send a POST request using curl:

[snip]

I'm feeling a bit baffled about what is expected here, so could someone shed light on what I'm doing wrong?

I'm not familiar with curl command line. But when I was testing rest
interface, I did it with wget, and you need to add the Content-Type
header. If you notice in your request, the content-type is
"application/x-www-form-urlencoded". Here is what I'd pass using wget:

wget --header=Content-Type:application/json --post-data='{"data":
"there"}' http://localhost:8080/

I'm sure curl supports a similar thing.

N.B. what I'd really like is to be able to avoid JSON (de)serialization entirely and for the REST API to just hand over the post body directly to the handling method, but IIUC the design is currently tied to JSON ... ?

You can use registerWebInterface, and then process the data directly
from HTTPServerRequest parameter. As far as I know, if you want to use
registerRestInterface, you have to play by those rules (Json only). I
have crappy parts of my code where I have to register both a rest
interface for the normal data, and then register web interface when I
want to do something out of the ordinary (including streaming back Json
data!). You may be able to use a @before or @after attribute to process
the data differently.

I'm also just getting into vibe.d, so take my advice with a grain of
salt, maybe there is a way :)

-Steve