【问题标题】:What are the options for REST frameworks in D? [closed]D 中的 REST 框架有哪些选择? [关闭]
【发布时间】:2013-10-16 02:16:46
【问题描述】:

我想使用 创建一个 RESTful Web 应用程序。

值得考虑的最积极维护和贡献的项目是什么?对这些 Web 框架的优缺点进行简短的比较会很好。

我的搜索只让我找到了一个项目,这似乎是一个出色的框架: vibe.d

还有像这样的本质上最小的项目吗?

【问题讨论】:

  • 不幸的是,此类“购物”问题并不适合 SO。
  • 我并不是真的在购买框架。关于 Java Web 框架的比较有很多问题,Python、Ruby 等也是如此。我相信作为一门优秀的语言,D 应该有一个关于其 Web 框架比较的 stackoverflow 问题。
  • 我认为这些问题也不合适。但它们就是它们,并且确实存在。我认为这更适合 D 标签上的信息页面(研究完成;发布的信息链接,而不是问题)。
  • 我不认为比较问题应该在语言网站上而不是在 stackoverflow 上。 D info page 可以列出用 D 编写的 web 框架,(这是 Haskell 的 info page 所做的)。但是,积极研究和使用过这些框架的人,也就是程序员,可以告诉别人每个框架的优缺点。如果您正在寻找软件包/框架的清单,该语言的信息页面会更好,但不能用于比较。

标签: d sinatra rest web d vibed


【解决方案1】:

我听说过 vibe.d http://vibed.org/ 的好消息

不过,我从未亲自使用过它,因为我在 vibe 出现之前就编写了自己的库。 https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff

vibe 有更好的文档记录,所以你最好去那里,但我的库是这样工作的:

cgi.d 是基本的 Web 界面(如果需要,在编译时使用 -version=embedded_httpd 以使用它自己的 Web 服务器而不是 CGI),我在一个名为 web.d 的单独文件中提供了一些 RESTy 的东西。它依赖于 cgi.d、dom.d、characterencodings.d 和 sha.d。您可能还需要 database.d 和 mysql.d 来连接到 mysql 数据库。

web.d 的工作方式是您只需编写函数,它会自动将它们映射到 url 并格式化数据。

http://arsdnet.net/cgi-bin/apidemo/add-some-numbers

该部分的源代码是:

import arsd.web;
class MySite : ApiProvider {
     export int addSomeNumbers(int a, int b) { return a+b; }
}
mixin FancyMain!MySite;

web.d 会自动生成您在此处看到的表单,将 url 解析为给定的类型,并将返回值格式化为 html、json 或其他格式(例如,可以将对象制成表格)。

还有一个envelopeFormat url param,可以把它包装成更多的json,最适合机器消费: http://arsdnet.net/cgi-bin/apidemo/add-some-numbers?a=1&b=2&format=json&envelopeFormat=json

我的 github 中的 web.d.php 显示了一种使用它的方式,web.d 本身会自动生成 JavaScript 函数以从客户端调用:

MySite.addSomeNumbers(10, 20).get(function(answer) { alert("Server replied: " + answer); });

答案将是 D 函数返回的类型。

如果您不想要/不需要自动函数包装,cgi.d 单独提供访问基本信息和编写函数的权限:

void requestHandler(Cgi cgi) {
    // there's cgi.get["name"], cgi.post["name"], or cgi.request("name"), kinda like php
    cgi.write("hello ", cgi.request("name"));
}
mixin GenericMain!requestHandler;

但是,是的,我的库中存在的大多数文档只是我在论坛上谈论它......我认为一旦你完成了一个功能,就不难弄清楚,但我有偏见!

编辑:从我下面的评论中复制/粘贴,因为它与真正获得 RESTy 非常相关:

实际上,我确实尝试过将 url 映射到对象并且动词经过的想法:web.d 还包含一个 ApiObject 类,该类如下: /obj/name -> new Obj("name");然后在其上调用适当的方法。所以 GET /obj/name 调用 (new Obj("name")).GET();,同样适用于 POST、PUT 等。然后 /obj/name/foo 调用 (new Obj("name").foo() ; 使用与我在上面描述的函数相同的规则。

但是我没有像普通函数那样使用它,因为它仍然有些错误......而且它仍然有些错误,因为我没有足够的使用它来坐下来适应它!哈哈

您通过编写一个 ApiObject 类然后将其别名到 ApiProvider 中来使用它:

import arsd.web;
class MySite : ApiProvider {
     export int addSomeNumbers(int a, int b) { return a+b; }
     alias MyObject obj; // new, brings in MyObject as /obj/xxx/
}

当然,还要定义对象:

class MyObject : ApiObject {
    CoolApi parent;
    string identifier;
    this(CoolApi parent, string identifier) {
    this.parent = parent;
    this.identifier = identifier;

    /* you might also want to load any existing object from a database or something here, using the identifier string, and initialize other members */
    // for now to show the example, we'll just initialize data with dummy info

    data.id = 8;
    data.name = "MyObject/" ~ identifier;
    }

    /* define some members as a child struct so we can return them later */
    struct Data {
    int id;
    string name;
    Element makeHtmlElement() {
        // for automatic formatting as html
        auto div = Element.make("div");
        import std.conv;
        div.addChild("span", to!string(id)).addClass("id");
        div.appendText(" ");
        div.addChild("span", name).addClass("name");
        return div;
    }
    }

    Data data;

    export Data GET() {
    return data;
    }

    export Data POST(string name) {
    parent.ensureGoodPost(); // CSRF token check

    data.name = name;
    // normally, you'd commit the changes to the database and redirect back to GET or something like that, but since we don't have a db we'll just return the modified object

    return data;
    }

// property accessors for the data, if you want
    export int id() {
    return data.id;
    }
}

mixin FancyMain!MySite;

然后就可以访问了:

http://arsdnet.net/cgi-bin/apidemo2/obj/cool/

顺便说一句,尾部斜线是强制性的:这是我尚未解决的突出错误之一。 (尾部的斜杠代码比它应该的要复杂,使它看起来更难修复。)

无论如何,您可以通过 makeHtmlElement 看到对象本身呈现为 html。这是展示其他格式的好时机:

http://arsdnet.net/cgi-bin/apidemo2/obj/cool/?format=table

table,也可以试试 csv,当然还有 json

http://arsdnet.net/cgi-bin/apidemo2/obj/cool/?format=json

或用于机器消耗: http://arsdnet.net/cgi-bin/apidemo2/obj/cool/?format=json&envelopeFormat=json

并且该属性也可用: http://arsdnet.net/cgi-bin/apidemo2/obj/cool/id

另一个主要的突出错误是自动生成的 Javascript 函数根本无法访问子对象。它们仅适用于顶级 ApiProvider 上的功能。另一个比看起来更难修复的错误,我并不是特别想这样做,因为顶级函数无论如何都可以完成。当然,您可以自己在 xmlhttprequest 上创建 URL 并以这种方式访问​​它。

让我们也通过一个快速表单来演示 POST:

http://arsdnet.net/cgi-bin/apidemo2/poster

您可以提交一些东西并看到 POST 处理程序确实重置了名称。 (顺便说一句,该动作有斜杠:没有它,它会默默地重定向你!我真的应该解决这个问题。)

无论如何,尽管存在错误,但它的核心仍然有效,并且可能是目前最接近成熟 REST D 的东西。

【讨论】:

  • cgi.d 的另一个几乎没有记录的特性是您可以从命令行进行测试,因此如果您运行:“./apidemo2 GET /obj/cool/”,它会在此处显示输出。 cgi.d 中有一个关于解释某些选项的构造函数的注释。在 cgi.d 中搜索“--cookie”,您会看到该评论。其他命令行选项是查询字符串或 POST 参数,具体取决于方法。
  • 我看到你写了这么多关于你的框架的文字,为什么不借此机会回答一个问题并同时制作文档。最终,您不必从“更好地记录氛围”开始。
  • 是的,我一直想建立一个网站和博客或其他东西,但还没有开始。我花了很多时间回答问题,但实际上无法通过网站设置取悦自己;我讨厌他们。
【解决方案2】:

在撰写本文时,据我所知,还没有构建真正的 RESTful Web 服务的框架。但是,您应该能够轻松地在他上面提到的vibe.dAdam's web modules 之上构建一个。

【讨论】:

  • 我实际上确实玩过将 url 映射到对象并且动词经过的想法:web.d 还包含一个 ApiObject 类,它可以: /obj/name -> new Obj("name" );然后在其上调用适当的方法。所以 GET /obj/name 调用 (new Obj("name")).GET();,同样适用于 POST、PUT 等。然后 /obj/name/foo 调用 (new Obj("name").foo() ; 使用与我在上面描述的函数相同的规则。但是我没有像普通函数那样使用它,因为它仍然有些错误....而且它仍然有些错误,因为我不使用它足以坐下来适应一切!哈哈
  • 请注意,我刚刚在我的答案中编辑了一些关于 ApiObject 功能的内容
  • 请注意 RESTFul 一词前面的 true 一词... ;) 我谦虚地相信 60% 的将 REST 放在其描述中的框架和 API 并不是真正的 REST。 ..不要误会我的意思,我不认为这很糟糕,只是真正的RESTfulness很难......
【解决方案3】:

你可以看看我正在构建什么。仍然非常 alpha,但我正在尝试在 D 中构建一个类似 Rails 的框架:http://jaredonline.github.io/action-pack/

【讨论】:

    【解决方案4】:

    我知道这是一个很晚的答案,但我想有一天可能会有人过来,因为它已经很长时间了,而且 D 社区发生了很多变化,尤其是在 Web 开发方面。

    使用 Diamond,您可以编写 RESTful Web 应用程序,而无需将一些东西拼凑在一起,因为它在框架内支持它。

    http://diamondmvc.org/docs/backend/#rest

    【讨论】:

      【解决方案5】:

      你可以试试Hunt Framework

      路线设置

      GET    /user/{id}    user.detail
      

      app/UserController.d 源代码:

      module app.controller.UserController;
      
      import hunt.framework;
      
      class User
      {
          int id;
          string name;
      }
      
      class UserController : Controller
      {
          mixin MakeController;
      
          @Action
          JsonResponse detail(int id)
          {
              auto user = new User;
              user.id = id;
              user.name = "test";
      
              return new JsonResponse(user);
          }
      }
      

      请求http://localhost:8080/user/123

      {
          "id": 123,
          "name": "test"
      }
      

      【讨论】:

      • 哪种进程模型遵循 Hunt 框架?异步?多线程? ...
      猜你喜欢
      • 2015-07-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-19
      • 1970-01-01
      • 2010-09-21
      • 2011-01-30
      • 1970-01-01
      • 2010-09-23
      相关资源
      最近更新 更多