如何在 Vibe.d 中使用 HTTP 代码 return JSON?
How can I return JSON with HTTP code in Vibe.d?
我不仅要returnJSON,还要JSONHTTP响应码
我通过 URLRouter 注册 REST 接口:
router.registerRestInterface(new ClientServerAPI);
我的 REST 实现示例:
module clienserverapi.clientserver;
import api.clientserver;
import models.replies.client_versions;
/**
Implementation of Client-Server API.
*/
class ClientServerAPI : IClientServerAPI {
@safe:
ClientVersions getSupportedClientVersions() {
bool[string] unstableFeatures;
return ClientVersions(supportedVersions.dup, unstableFeatures);
}
}
在 REST 接口生成器中,响应代码是自动处理的,并且由于您无法将 HTTPServerResponse/HTTPServerRequest 参数传递到 REST 方法中,因此您无法控制 returned 的状态.
但是有一些 built-in 状态需要处理:
- 200/204 return根据内容编辑
- 400 参数不匹配的错误请求
- 404 未找到不匹配的路线
- 500 内部服务器错误return大多数异常
- (除调试模式外)发送未授权/错误请求/禁止
另请参阅:REST interface documentation
并且您可以使用 HTTPStatusException 控制任何状态代码,但是它被视为错误并将导致预定义错误 json,其中 statusMessage 作为异常消息集和 return是您传递给它的 HTTP 状态代码。 (这可能是您想要的错误处理方式)
您还可以通过设置 errorHandler to a RestErrorHandler delegate in your RestInterfaceSettings.
来更改错误的外观
或者,根据您要执行的操作,您可以使用 WebInterface,它很像 rest 界面,但没有 REST 界面的一些便利功能,而是可以完全访问 request/response 参数,基本上可以像普通的 http 路由一样做任何事情,并且有一些 other 方便你可以使用的功能。
理论上,如果您想 return 使用您的数据自定义成功代码,您可以使用有效的 HTTP 状态代码滥用 errorHandler + HTTPStatusException,但我不鼓励这样做,而是使用 Web 界面,如果那是您想要的之后。
但是,如果您只想使用自定义错误代码和自定义但一致的错误页面,那么我肯定会使用带有 errorHandler 的 REST 接口。
您现在可以看起来像这样:
import vibe.vibe;
import std.uni;
@safe:
void main() {
auto server = new HTTPServerSettings;
server.port = 3000;
server.bindAddresses = ["::1", "127.0.0.1"];
auto router = new URLRouter;
RestInterfaceSettings settings = new RestInterfaceSettings();
// this is how the error page will look on any thrown exception (like HTTPStatusException)
settings.errorHandler = (HTTPServerRequest req, HTTPServerResponse res,
RestErrorInformation error) @safe {
res.writeJsonBody([
// design this however you like
"ok": Json(false),
"error": serializeToJson([
"status": Json(cast(int)error.statusCode),
"message": Json(error.exception.msg),
"parent": Json("/api/something")
])
]);
};
router.registerRestInterface(new Impl, settings);
listenHTTP(server, router);
runApplication();
}
interface RestAPI {
string getGreeting(string name);
}
class Impl : RestAPI {
string getGreeting(string name)
{
// throw an HTTP Bad Request error when name is empty
if (name.length == 0)
throw new HTTPStatusException(HTTPStatus.badRequest, "Name parameter cannot be empty!");
// throw an HTTP Conflict error code when name is Bob
if (sicmp(name, "bob") == 0)
throw new HTTPStatusException(HTTPStatus.conflict, "Server cannot greet Bob!");
return "Hello, " ~ name ~ "!";
}
}
然后您的服务器将响应如下内容:
{
"ok": false,
"error": {
"message": "Server cannot greet Bob!",
"status": 409,
"parent": "/api/something"
}
}
你可以试试 hunt 框架,Rest 的示例代码 api:
module app.controller.myapi;
import hunt.framework;
import app.message.UserMessage;
class MyapiController : Controller
{
mixin MakeController;
@Action
JsonResponse test()
{
UserMessage user;
user.id = 1;
user.name = "MyName";
user.email = "test@domain.com";
return new JsonResponse(user);
}
}
您的响应结构:
module app.message.ResultMessage;
struct UserMessage
{
int id;
string name;
string email;
}
响应结果为:
[ "id": 1, "name": "MyName", "email": "test@domain.com" ]
我不仅要returnJSON,还要JSONHTTP响应码
我通过 URLRouter 注册 REST 接口:
router.registerRestInterface(new ClientServerAPI);
我的 REST 实现示例:
module clienserverapi.clientserver;
import api.clientserver;
import models.replies.client_versions;
/**
Implementation of Client-Server API.
*/
class ClientServerAPI : IClientServerAPI {
@safe:
ClientVersions getSupportedClientVersions() {
bool[string] unstableFeatures;
return ClientVersions(supportedVersions.dup, unstableFeatures);
}
}
在 REST 接口生成器中,响应代码是自动处理的,并且由于您无法将 HTTPServerResponse/HTTPServerRequest 参数传递到 REST 方法中,因此您无法控制 returned 的状态.
但是有一些 built-in 状态需要处理:
- 200/204 return根据内容编辑
- 400 参数不匹配的错误请求
- 404 未找到不匹配的路线
- 500 内部服务器错误return大多数异常
- (除调试模式外)发送未授权/错误请求/禁止
另请参阅:REST interface documentation
并且您可以使用 HTTPStatusException 控制任何状态代码,但是它被视为错误并将导致预定义错误 json,其中 statusMessage 作为异常消息集和 return是您传递给它的 HTTP 状态代码。 (这可能是您想要的错误处理方式)
您还可以通过设置 errorHandler to a RestErrorHandler delegate in your RestInterfaceSettings.
来更改错误的外观或者,根据您要执行的操作,您可以使用 WebInterface,它很像 rest 界面,但没有 REST 界面的一些便利功能,而是可以完全访问 request/response 参数,基本上可以像普通的 http 路由一样做任何事情,并且有一些 other 方便你可以使用的功能。
理论上,如果您想 return 使用您的数据自定义成功代码,您可以使用有效的 HTTP 状态代码滥用 errorHandler + HTTPStatusException,但我不鼓励这样做,而是使用 Web 界面,如果那是您想要的之后。
但是,如果您只想使用自定义错误代码和自定义但一致的错误页面,那么我肯定会使用带有 errorHandler 的 REST 接口。
您现在可以看起来像这样:
import vibe.vibe;
import std.uni;
@safe:
void main() {
auto server = new HTTPServerSettings;
server.port = 3000;
server.bindAddresses = ["::1", "127.0.0.1"];
auto router = new URLRouter;
RestInterfaceSettings settings = new RestInterfaceSettings();
// this is how the error page will look on any thrown exception (like HTTPStatusException)
settings.errorHandler = (HTTPServerRequest req, HTTPServerResponse res,
RestErrorInformation error) @safe {
res.writeJsonBody([
// design this however you like
"ok": Json(false),
"error": serializeToJson([
"status": Json(cast(int)error.statusCode),
"message": Json(error.exception.msg),
"parent": Json("/api/something")
])
]);
};
router.registerRestInterface(new Impl, settings);
listenHTTP(server, router);
runApplication();
}
interface RestAPI {
string getGreeting(string name);
}
class Impl : RestAPI {
string getGreeting(string name)
{
// throw an HTTP Bad Request error when name is empty
if (name.length == 0)
throw new HTTPStatusException(HTTPStatus.badRequest, "Name parameter cannot be empty!");
// throw an HTTP Conflict error code when name is Bob
if (sicmp(name, "bob") == 0)
throw new HTTPStatusException(HTTPStatus.conflict, "Server cannot greet Bob!");
return "Hello, " ~ name ~ "!";
}
}
然后您的服务器将响应如下内容:
{
"ok": false,
"error": {
"message": "Server cannot greet Bob!",
"status": 409,
"parent": "/api/something"
}
}
你可以试试 hunt 框架,Rest 的示例代码 api:
module app.controller.myapi;
import hunt.framework;
import app.message.UserMessage;
class MyapiController : Controller
{
mixin MakeController;
@Action
JsonResponse test()
{
UserMessage user;
user.id = 1;
user.name = "MyName";
user.email = "test@domain.com";
return new JsonResponse(user);
}
}
您的响应结构:
module app.message.ResultMessage;
struct UserMessage
{
int id;
string name;
string email;
}
响应结果为:
[ "id": 1, "name": "MyName", "email": "test@domain.com" ]