我想使用d创建一个 RESTful Web 应用程序。
哪些是值得考虑的最积极维护和贡献的项目?对这些 Web 框架的优缺点进行简短的比较会很好。
我的搜索只让我找到了一个项目,这似乎是一个出色的框架: vibe.d
是否还有其他像sinatra这样的本质上最小的项目?
我听说过关于 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 或其他格式(例如,可以将对象制成表格)。
还有一个信封格式 url 参数,可以将其包装在更多的 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); });
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
表,也可以试试 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 的东西。
在撰写本文时,据我所知,还没有构建真正的 RESTful Web 服务的框架。但是,您应该能够轻松地在vibe.d或Adam上面已经提到的 web 模块之上构建一个。
你可以看看我在做什么。仍然非常 alpha,但我正在尝试在 D 中构建一个类似 Rails 的框架:http: //jaredonline.github.io/action-pack/
我知道这是一个很晚的答案,但我想有一天有人可能会来,因为它已经很长时间了,而且 D 社区发生了很多变化,尤其是在 Web 开发方面。
使用 Diamond,您可以编写 RESTful Web 应用程序,而无需将某些东西拼凑在一起,因为它在框架内支持它。
你可以试试Hunt 框架。
GET /user/{id} user.detail
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);
}
}
{
"id": 123,
"name": "test"
}