JSON, Networking and Web Development
44.1 JSON
Typed (de)serialization: vibe.data.json (serializeToJson/deserializeJson!T), asdf, mir-ion (very fast; JSON/YAML/MsgPack/Ion), jsonizer, painlessjson.
Other formats: std.csv (csvReader!Record(text, null)), dyaml (YAML), toml (toml-d), sdlang-d, msgpack-d, protobuf-d.
import std.json;
auto j = parseJSON(`{"name": "Ana", "tags": ["a", "b"], "age": 30}`);
writeln(j["name"].str, " ", j["age"].integer, " ", j["tags"][0].str);
if ("missing" in j) {}
JSONValue obj = ["id": JSONValue(1), "ok": JSONValue(true)];
obj["list"] = JSONValue([1, 2, 3]);
writeln(obj.toString, "\n", obj.toPrettyString);44.2 HTTP Client and Sockets
Third-party: requests (ikod/dlang-requests), the vibe.d HTTP client, arsd.http2.
import std.net.curl;
auto html = get("https://dlang.org");
auto resp = post("https://httpbin.org/post", ["key": "value"]);
download("https://example.com/file.zip", "file.zip");
auto http = HTTP("https://api.github.com/repos/dlang/dmd");
http.addRequestHeader("User-Agent", "d-client");
http.onReceive = (ubyte[] data) { write(cast(string) data); return data.length; };
http.perform();
import std.socket;
auto server = new TcpSocket();
server.setOption(SocketOptionLevel.SOCKET, SocketOption.REUSEADDR, true);
server.bind(new InternetAddress(8080));
server.listen(10);
auto client = server.accept();
char[1024] buf;
auto n = client.receive(buf[]);
client.send(buf[0 .. n]);
client.close();44.3 vibe.d Web Framework
Features: fiber-based async I/O, REST interface generation (server and client from one interface), Diet templates, WebSockets, sessions, MongoDB/Redis drivers, TLS, an HTTP/2 add-on.
Other web frameworks: handy-httpd, serverino, hunt-framework, arsd.cgi (CGI/FastCGI/SCGI/embedded server), archttp.
// dub.json: "dependencies": { "vibe-d": "~>0.10" }
import vibe.vibe;
void main()
{
auto router = new URLRouter;
router.get("/", (req, res) { res.writeBody("Hello from vibe.d!"); });
router.get("/hello/:name", &hello);
router.registerWebInterface(new WebApp);
router.registerRestInterface(new ApiImpl);
auto settings = new HTTPServerSettings;
settings.port = 8080;
settings.bindAddresses = ["127.0.0.1"];
listenHTTP(settings, router);
runApplication();
}
void hello(HTTPServerRequest req, HTTPServerResponse res)
{
res.writeJsonBody(["greeting": "Hello " ~ req.params["name"]]);
}
class WebApp
{
void index() { render!("index.dt"); } // Diet templates (Pug-like)
void postLogin(string username, string password) { redirect("/"); } // form fields auto-mapped
}
@path("/api")
interface Api { @method(HTTPMethod.GET) string getStatus(); User getUser(int id); }
class ApiImpl : Api { string getStatus() { return "ok"; } User getUser(int id) { return User(id, "Ana"); } }44.4 Databases
ddbc (JDBC-like for MySQL/PostgreSQL/SQLite), dpq2 (PostgreSQL), mysql-native, d2sqlite3, hibernated (ORM), the vibe.d MongoDB/Redis clients, arsd.database.
import d2sqlite3;
auto db = Database("app.db");
db.run("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)");
auto stmt = db.prepare("INSERT INTO users (name) VALUES (:name)");
stmt.inject("Ana"); // parameterized
foreach (row; db.execute("SELECT id, name FROM users")) writeln(row["id"].as!int, " ", row["name"].as!string);