代码之家  ›  专栏  ›  技术社区  ›  GeneQ

如何在Perl中实现RESTfulAPI?

  •  8
  • GeneQ  · 技术社区  · 15 年前

    我正在尝试在Perl中实现一个RESTfulAPI。我目前的想法是简单地用regex解析路径_-info,然后将请求分派到适当的子例程,然后该子例程将为请求的资源输出JSON、XML甚至XHTML。

    例如,要检索关于用户1234的信息,RESTful客户机应该在以下位置找到它:

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

    下面是我第一次尝试实现RESTfulAPI的框架代码:

    模型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块会变得非常大。

    期待听到您的意见,使这个代码更好。

    7 回复  |  直到 6 年前
        1
  •  8
  •   MkV    15 年前

    我将使用类似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' },
    ],
    

    (也可以使用自动休息或自动休息)

    您可以为每种类型的事物使用单独的cgi::application类(或者只使用cgi-app-controller类方法中的类)。

    应用程序还附带了用于输出XML、JSON或从模板生成的文本的插件。

    cgi应用程序(和c::a::d)是cgi应用程序,可以在cgi、fastcgi或mod_perl下使用(很少或没有更改)。默认情况下,C::A::D也是mod ouperl PerlHandler。

        2
  •  16
  •   robert_b_clarke    12 年前

    对于轻量级的RESTAPI,我会考虑mojolicous。请求路由非常简单,内置的JSON渲染器和用户代理使简单的RESTAPI的开发在我的经验中非常简单。

    如果你的应用程序相对较小,那么 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;
    
        3
  •  1
  •   Quentin    15 年前
        4
  •  1
  •   Thariama    12 年前

    为什么不使用已经实现的模块 Apache2::REST ? 一切都在那里。

        5
  •  0
  •   Gerd    9 年前

    简单的解决方案:

     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;
     }
    
        6
  •  -1
  •   chb    6 年前

    简单的解决方案-启用变量调整 $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;
     }
    
        7
  •  -3
  •   maozet    15 年前