On Mon, 20 Oct 2014 13:13:58 GMT, Geod24 wrote:

On Thu, 16 Oct 2014 13:49:57 GMT, Sönke Ludwig wrote:

There are currently two ways to achieve this:

  • throw a HTTPStatusException with the appropriate status code
  • use @after to get direct access to the response object

The second option should work similar to this:

interface MyService {
	static void setReturnCode(HTTPServerRequest req, HTTPServerResponse res)
	{
		res.statusCode = 201;
	}

	@after!setReturnCode
	void getSomeResource();
}

Both solutions may not be very nice in certain situations, so I think there should be another way to achieve the same result, but simpler. Maybe by encoding it in the return value, using an out parameter, or by adding higher level attributes (@createsResource, @processesAsynchronously, @resourceType!(RT.create)) or a low level attribute (@httpStatusCode). Do you (or anyone else) have an opinion on this?

Once again, @after is on the interface to do server-side work. Unless it's handled on the class level, I'd say, don't use it.

You are right about the server-side of course, I forgot about that.

As per the return code, this is a problem that has been discussed previously. IIRC, Dicebot take on this subject is that exception-based handling is awfully slow (and wrong, in case you return a 2XX response).

Well, I strongly disagree with the general rejection of exceptions, because IMO bad performance of throwing an exception is a bug, rather than a systematic issue. I also thought that most of it has already been fixed (apart from requiring a GC allocation per exception).

However, of course it's correct that exceptions are the wrong tool for success codes.

It's a problem I've been exploring, and I don't believe an additional parameter would be the solution, for the exact same reason : it's on the interface while the return code is server specific.

However, there is no conceptual difference between using the return value or an out parameter w.r.t. the client side.

In addition, the return code might depend on the function. The current solution I'm exploring is to allow a special behavior based on the return type, something along those lines:

interface MyApi {
   RestResponse!string getMessage();
}
class MyApiImpl : MyApi{
   override RestResponse!string getMessage() {
     // Works, as RestResponse will be a struct.
     // Return code is 200.
     return "Test";
     // Return code is 204.
     return null; // Or "", as null == ""
     // Full control over the return.
     return RestResponse!string("Wait for it...", 202);
   }
}

I think using semantic attributes (à la @createsResource) is the most generally useful and clean way. A return value based approach still has the issue that it leaks very HTTP specific information to the interface. At least for most cases I'd like to avoid that, but it should be a good additional tool to have for those rare situations where you need more control.