如何在Vibe.d中使用HTTP代码返回JSON?

时间:2019-07-13 14:57:29

标签: d vibed

我不仅要返回JSON,还要返回HTTP响应代码。

我通过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);
    }
}

2 个答案:

答案 0 :(得分:3)

在REST接口生成器中,响应代码是自动处理的,并且由于无法将HTTPServerResponse / HTTPServerRequest参数传递到REST方法中,因此您无法控制返回什么状态。

但是有一些内置状态可以处理:

    根据内容返回
  • 200/204
  • 400错误要求不匹配的参数
  • 找不到404条不匹配的路线
  • 在大多数异常中返回500个内部服务器错误
  • (在调试模式之外)未授权/错误请求/禁止发送

另请参阅:REST interface documentation

,您可以使用HTTPStatusException控制任何状态代码,但是它将被视为错误,并且会导致预定义的错误json,其中将statusMessage作为异常消息集并返回传递给它的HTTP状态代码。 (这可能是您要进行错误处理的目的)

您还可以通过将errorHandler设置为RestInterfaceSettings中的RestErrorHandler委托来更改错误的外观。

或者,根据您要执行的操作,您可以使用WebInterface,它非常类似于rest接口,但是没有REST接口具有的一些便捷功能,但是可以完全访问请求/响应参数,并且基本上可以像正常的http路由一样执行任何操作,并具有一些可以使用的 other 便捷功能。

理论上,如果您想随数据返回自定义成功代码,则可以使用有效的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"
    }
}

答案 1 :(得分:0)

您可以尝试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" ]