Function registerRestInterface
Registers a server matching a certain REST interface.
URLRouter registerRestInterface(TImpl)
(
URLRouter router,
TImpl instance,
RestInterfaceSettings settings = null
);
URLRouter registerRestInterface(TImpl)
(
URLRouter router,
TImpl instance,
MethodStyle style
);
URLRouter registerRestInterface(TImpl)
(
URLRouter router,
TImpl instance,
string url_prefix,
MethodStyle style = MethodStyle .lowerUnderscored
);
Servers are implementation of the D interface that defines the RESTful API.
The methods of this class are invoked by the code that is generated for
each endpoint of the API, with parameters and return values being translated
according to the rules documented in the vibe
module
documentation.
A basic 'hello world' API can be defined as follows:
@path("/api/")
interface APIRoot {
string get();
}
class API : APIRoot {
override string get() { return "Hello, World"; }
}
void main()
{
// -- Where the magic happens --
router .registerRestInterface(new API());
// GET http://127.0.0.1:8080/api/ and 'Hello, World' will be replied
listenHTTP("127.0.0.1:8080", router);
runApplication();
}
As can be seen here, the RESTful logic can be written inside the class without any concern for the actual HTTP representation.
Return value
By default, all methods that return a value send a 200 (OK) status code, or 204 if no value is being returned for the body.
Non-success:
In the cases where an error code should be signaled to the user, a
HTTPStatusException
can be thrown from within the method. It will be
turned into a JSON object that has a statusMessage
field with the
exception message. In case of other exception types being thrown, the
status code will be set to 500 (internal server error), the
statusMessage
field will again contain the exception's message, and,
in debug mode, an additional statusDebugMessage
field will be set to
the complete string representation of the exception
(Exception
), which usually contains a stack trace useful for
debugging.
Returning data
To return data, it is possible to either use the return value, which
will be sent as the response body, or individual ref
/out
parameters
can be used. The way they are represented in the response can be
customized by adding @viaBody
/@viaHeader
annotations on the
parameter declaration of the method within the interface.
In case of errors, any @viaHeader
parameters are guaranteed to
be set in the response, so that applications such as HTTP basic
authentication can be implemented.
Template Params
TImpl = Either an interface type, or a class that derives from an interface. If the class derives from multiple interfaces, the first one will be assumed to be the API description and a warning will be issued.
Parameters
Name | Description |
---|---|
router | The HTTP router on which the interface will be registered |
instance | Server instance to use |
settings | Additional settings, such as the MethodStyle or the prefix |
See Also
RestInterfaceClient
class for an automated way to generate the
matching client-side implementation.
Example
This is a very limited example of REST interface features. Please refer to the "rest" project in the "examples" folder for a full overview.
All details related to HTTP are inferred from the interface declaration.
@path("/")
interface IMyAPI
{
@safe:
// GET /api/greeting
@property string greeting();
// PUT /api/greeting
@property void greeting(string text);
// POST /api/users
@path("/users")
void addNewUser(string name);
// GET /api/users
@property string[] users();
// GET /api/:id/name
string getName(int id);
// GET /some_custom_json
Json getSomeCustomJson();
}
// vibe.d takes care of all JSON encoding/decoding
// and actual API implementation can work directly
// with native types
class API : IMyAPI
{
private {
string m_greeting;
string[] m_users;
}
@property string greeting() { return m_greeting; }
@property void greeting(string text) { m_greeting = text; }
void addNewUser(string name) { m_users ~= name; }
@property string[] users() { return m_users; }
string getName(int id) { return m_users[id]; }
Json getSomeCustomJson()
{
Json ret = Json .emptyObject;
ret["somefield"] = "Hello, World!";
return ret;
}
}
// actual usage, this is usually done in app.d module
// constructor
void static_this()
{
import vibe .http .server, vibe .http .router;
auto router = new URLRouter;
router .registerRestInterface(new API());
listenHTTP(new HTTPServerSettings(), router);
}