簡體   English   中英

如何在 Perl 中實現 RESTful API?

[英]How can I implement a RESTful API in Perl?

我正在嘗試在 Perl 中實現一個 RESTful API。 我目前的想法是簡單地使用正則表達式解析 path_info,然后將請求分派到適當的子程序,然后該子程序將為請求的資源吐出 JSON、XML 甚至 XHTML。

例如,要檢索有關用戶 1234 的信息,RESTful 客戶端應在以下位置找到它:

http://example.com/model.pl/users/1234

下面是我第一次嘗試實現 RESTful API 的框架代碼:

模型.pl

#!/usr/bin/perl -w
use strict;
use CGI;

my $q = CGI->new();

print $q->header('text/html');

my $restfuluri  = $q->path_info;

if      ($restfuluri =~ /^\/(questions)\/([1-9]+$)/) { questions($1, $2); }
elsif   ($restfuluri =~ /^\/(users)\/([1-9]+$)/)     { users($1, $2); }


sub questions
{
      my $object = shift;
      my $value  = shift;

      #This is a stub, spits out JSON or XML when implemented.
      print $q->p("GET question : $object -> $value");
}

sub users
{
      my $object = shift;
      my $value  = shift;

      #This is a stub, spits out JSON or XML when implemented.
      print $q->p("GET user: $object -> $value");
}

在我繼續之前,我想聽聽經驗豐富的 Perl 黑客的意見,我的基本想法是否正確,以及這種方法在性能方面是否存在任何嚴重缺陷。

我可以想象,一段時間后,if/else 塊會變得非常大。

期待聽到您的意見,以使此代碼更好。

對於輕量級 REST API,我會查看 Mojolicious。 根據我的經驗,請求路由非常簡單,內置的 JSON 渲染器和用戶代理使簡單 REST API 的開發變得非常簡單。

如果您的應用程序相對較小,那么Mojo::Lite可能會滿足您的要求。 例如,您可以執行以下操作:

use Mojolicious::Lite;

get '/questions/(:question_id)' => sub {
    my $self = shift;
    my $result = {};
    # do stuff with $result based on $self->stash('question_id')
    return $self->render_json($result)
}

app->start;

我會使用像 CGI::Application::Dispatch 這樣的東西,它讓我用變量和 REST 方法構建一個調度表,並讓你使用 CPAN 中的 CGI 和 CGI​​::Application 模塊。 例如:

table => [
'/questions/:id[get]'    => { rm => 'get_question' },
'/users/:id[get]'        => { rm => 'get_user' }, # OR
':app/:id[post]'         => { rm => 'update' }, # where :app is your cgi application module
':app/:id[delete]'       => { rm => 'delete' },
],

(或者您可以使用 auto_rest 或 auto_rest_lc)

您可以為每種類型的事物使用單獨的 CGI::Application 類(或僅在您的 cgi-app 控制器類方法中使用類)。

CGI::Application 還帶有用於輸出 XML、JSON 或從模板生成的文本的插件。

cgi-app(和 c::a::d)是 CGI 應用程序,可以在 CGI、FastCGI 或 mod_perl 下使用(很少或)沒有更改。 C::A::D 默認也是一個 mod_perl PerlHandler。

我會使用CatalystCatalyst::Controller::REST構建應用程序

為什么不使用已經實現的模塊Apache2::REST 它就在那里。

簡單的解決方案:

 use CGI;

 my $page  = new CGI;

 if( $ENV{ 'REQUEST_METHOD' } eq 'GET' ){

    my $data = <<json;
    {
    "isbn" : "123456",
    "title" : "Programming Perl",
    "author" : "L. Wall"
     }
 json

     print $page->header('application/json');

     print $data;
 }

我知道自從提出這個問題以來已經很長時間了,但我想提供一些更新的信息。

后面有一個非常有用的模塊,名為Net::API::REST,使用 Apache2 mod_perl。

您只需要設置 Apache,並創建您自己的繼承自Net::API::REST的模塊並創建一個用於定義端點映射的init方法,例如:

sub init
{
    my $self = shift( @_ );
    $self->{routes} =
    {
    # e.g. your API version 1
    1 =>
        {
        'favicon.ico' => $self->curry::noop,
        auth =>
            {
            google =>
                {
                _handler => $self->curry::oauth_google,
                callback => $self->curry::oauth_google(callback => 1),
                },
            linkedin =>
                {
                _handler => $self->curry::oauth_linkedin,
                callback => $self->curry::oauth_linkedin(callback => 1),
                },
            },
        },
        stripe => $self->curry::stripe,
    };
    $self->{api_version} = 1;
    $self->{supported_api_versions} = [qw( 1 )];
    $self->{default_methods} = [qw( GET POST )];
    $self->{supported_methods} = [qw( DELETE GET HEAD OPTIONS POST PUT )];
    $self->{supported_languages} = [qw( en-GB en fr-FR fr ja-JP )];
    $self->SUPER::init( @_ );
    return( $self );
}

當有人訪問您的端點之一時,您的相應方法將在強大環境的上下文中被調用,以用於回復請求。 查看模塊 metacpan 頁面以獲取更多信息。

簡單的解決方案 - 使用qq~~;$data進行變量調整qq~~; 保持所有代碼對齊。

 use CGI;

 my $page  = new CGI;

 if( $ENV{ 'REQUEST_METHOD' } eq 'GET' ){

    my $data = qq~
        {
            "isbn" : "123456",
            "title" : "Programming Perl",
            "author" : "L. Wall"
        }
    ~;

     print $page->header('application/json');

     print $data;
 }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM