【问题标题】:How to POST json file using REST API in Perl?如何在 Perl 中使用 REST API 发布 json 文件?
【发布时间】:2020-02-19 05:59:39
【问题描述】:

有一个应用程序每天生成多条记录,包含不同类型的属性,如 EmpName、EmpDesig 等,并以 JSON 格式存储。然后,此应用程序需要调用外部 REST api 来发布 JSON 格式的数据。外部应用程序将读取 JSON 文件,对其进行解析,并将每条记录存储在 PostgreSQL 数据库中。我如何在 Perl 中编写一个 REST api 来满足这个要求?我是否需要任何 Perl 框架,如 Mojolicious 或 Catalyst 或 Perl 模块,如 JSON、Rest::Client 是否足以满足此要求?请提出建议。

【问题讨论】:

  • 您的问题似乎有些混乱。那可能是因为您对术语不清楚。我认为您想将数据发布到 REST API,而不是编写 REST API。在这种情况下,您不需要框架,只需要像 LWP 这样的 HTTP 客户端,并且可能还需要 JSON encoder
  • 我需要编写一个 REST API,其他应用程序将使用它来发布数据。将发布数据的其他应用程序将不受我的控制。虽然为了测试,我还需要一个 POST 机制,否则我将如何测试它。

标签: json rest perl curl


【解决方案1】:

如果您确实想使用框架,它将大大简化您的代码。

您可以在一行中使用Dancer 框架:

perl -e 'use Dancer; any "/", sub{ warn to_dumper from_json request->body; return "ok" }; start'

但是,这个答案只是一个开始,它并不可靠,也不包含任何检查。

【讨论】:

  • 感谢您的建议,我一定会研究一下 Dancer 框架并深入研究它。
【解决方案2】:

您并不需要一个框架。使用Plack::Request 最容易上手。下一步是添加像Router::Resource 这样的路由器。当您发现这种编程风格太乏味时,升级到框架是有意义的。

use Plack::Request qw();
use HTTP::Status qw(
    HTTP_NO_CONTENT HTTP_NOT_FOUND HTTP_METHOD_NOT_ALLOWED
    HTTP_UNSUPPORTED_MEDIA_TYPE HTTP_UNPROCESSABLE_ENTITY
    HTTP_INTERNAL_SERVER_ERROR
);
use JSON::MaybeXS qw(decode_json);
use Syntax::Keyword::Try;
require IO::Handle;
use DBI qw();
require DBD::Pg;

my $app = sub {
    my ($env) = @_;
    my $req = Plack::Request->new($env);
    return $req->new_response(HTTP_NOT_FOUND)->finalize
        unless '/receive_json' eq $req->path_info;
    return $req->new_response(HTTP_METHOD_NOT_ALLOWED)->finalize
        unless 'POST' eq $req->method;
    return $req->new_response(HTTP_UNSUPPORTED_MEDIA_TYPE)->finalize
        unless $req->content_type =~ m'^application/.*json$';
    my $body = do {
        IO::Handle->input_record_separator(undef);
        $req->input->getline;
    };
    my $json;
    try {
        $json = decode_json $body;
    } catch {
        warn "could not decode JSON: $@";
        return $req->new_response(HTTP_UNPROCESSABLE_ENTITY)->finalize;
    }
    my $dbh;
    try {
        $dbh = DBI->connect(
            "dbi:Pg:dbname=$ENV{PGDATABASE}",
            $ENV{PGUSER},
            $ENV{PGPASSWORD},
            {pg_enable_utf8 => 1, RaiseError => 1}
        );
    } catch {
        warn "could not connect to database: $@";
        return $req->new_response(HTTP_INTERNAL_SERVER_ERROR)->finalize;
    }
    my $sth = $dbh->prepare(
        'insert into sometable(EmpName, EmpDesig) values (?,?)'
    );
    try {
        $sth->execute($json->{EmpName}, $json->{EmpDesig});
    } catch {
        warn "could not insert: $@";
        return $req->new_response(HTTP_INTERNAL_SERVER_ERROR)->finalize;
    }
    return $req->new_response(HTTP_NO_CONTENT)->finalize;
};

【讨论】:

    猜你喜欢
    • 2021-02-05
    • 1970-01-01
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    • 2016-03-25
    • 1970-01-01
    • 2012-08-06
    • 1970-01-01
    相关资源
    最近更新 更多