Book Image

D Web Development

By : Kai Nacke
Book Image

D Web Development

By: Kai Nacke

Overview of this book

D is a programming language with C-like syntax and static typing. The vibe.d framework builds on powerful D concepts like template meta-programming and compile-time function execution to provide an easy-to-use environment for web applications. The combination of a feature-rich web programming framework with a language compiling to native code solves two common issues in web development today: it accelerates your development and it results in fast, native web applications. Learning the vibe.d framework before you start your application will help you to choose the right features to reach your goal. This book guides you through all aspects of web development with D and the vibe.d framework. Covering the popular operating systems today, this guide starts with the setup of your development system. From the first Hello World-style application you will move on to building static web pages with templates. The concise treatment of web forms will give you all the details about form handling and web security. Using the abstractions of the web framework you will learn how to easily validate user input. Next, you will add database access to your application, providing persistent storage for your data. Building on this foundation, you will expose your component and integrate other components via REST. Learning about the internals of vibe.d you will be able to use low-level techniques such as raw TCP access. The vibe.d concepts can also be used for GUI clients, which is the next topic that you will learn. vibe.d is supported by an active community, which adds new functionality. This comprehensive guide concludes with an overview of the most useful vibe.d extensions and where to find them. It also shows you how to integrate these extensions in your application. The concepts are always illustrated with source code, giving you an insight into how to apply them in your application.
Table of Contents (17 chapters)
D Web Development
Credits
Foreword
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Creating your first web application


After you have set up your development environment, you are ready to create your first web application.

Using DUB to set up the project structure

The DUB package manager is used to package and build D applications and libraries. The tool can also be used to create the recommended project structure. You need to provide a folder name for your project and an optional project type. The project type can be minimal, vibe.d, or deimos. The project type determines which folders and files are created by running dub. The minimal project type creates the folders and files for a console application while vibe.d creates a vibe.d server application. The deimos project type is used for bindings to C libraries. (Refer to https://github.com/D-Programming-Deimos for the already available bindings.) If no project type is given, the package manager assumes minimal as the project type.

In a terminal, change your current directory to a folder where your projects should live. Run the following command:

$ dub init hello --type=vibe.d
Successfully created an empty project in '/<your path>/hello'.

This creates a new folder named hello. Let's look into the folder:

  • A file named dub.sdl was created

  • The public, source, and views folders were created

  • The source folder contains a file named app.d

The dub.sdl file is the package description and the app.d file is a sample vibe.d application. The public and views folders are for public and UI related files. Open the dub.sdl file in your editor:

name "hello"
description "A simple vibe.d server application."
copyright "Copyright © 2015, <yourid>"
authors "<yourid>"
dependency "vibe-d" version="~>0.7.23"
versions "VibeDefaultMain"

The file uses a description in Simple Declarative Language (SDLang). SDLang was designed for describing data structures and data types. It is well suited for configuration files and build specification. You can find the language specification at https://sdlang.org/.

In its simplest form, a declaration consists of a name and a value or an attribute. In the preceding dub.sdl file, dependency is a name, "vibe-d" is a value, and the key/value pair version="~>0.7.23" is an attribute. To create a nested data structure, you use { and } to specify the inner data.

It is also possible to specify more than one value or attribute. This creates a list or mapping table.

A name must start with a Unicode letter or an underscore. It can be then followed by zero or more Unicode letters, numbers, underscores, dashes, periods, and dollar signs. The format of the value depends on the data type. The most basic specifications are strings, integer numbers, and booleans: "vibe-d" and `vibe-d` are strings. 123 is a signed 32 bit number and 123L a signed 64 bit number. The possible Boolean values are true and false or on and off. The language specification defines some more data types such as date values. If you need to use these data types, please use the language specification available at the previously mentioned link to look up the exact format.

Note

Prior to DUB version 0.9.24, the package description was specified in a file called dub.json in the JSON format. While JSON support stays available (and is used by many available packages), this book uses the new SDLang format.

The fields in the dub.sdl file have the following meaning:

Name

Description

name

The name of the package. It is used to uniquely identify the package. It must only consist of lower case ASCII alpha-numeric characters, '-', and '_'. This field is required.

description

A brief description of the package.

copyright

The copyright declaration.

authors

The authors of the package.

dependency

A single dependency. The value specifies the name. Attributes version and path are used to specify the required version and a location in the file system.

versions

A list of version identifiers that to be defined during compilation.

There are many more fields available. You can find a complete list at http://code.dlang.org/package-format?lang=sdl.

Our goal is to create a web application with the vibe.d framework. DUB has automatically created a dependency to vibe.d in the package description for us.

Dependencies are specified as "name" version="version-string". The name is the name of the package that we are depending on. This explains why the name must be unique; without a unique name, the package manager would not be able to resolve the dependency.

The version string consists of an operator and the version number. This allows you to restrict the version of the required packages. The possible values are as follows:

  • Restrict to a certain minor version: "~>2.2.13", equivalent to ">=2.2.13 <2.3.0"

  • Restrict to a certain major version: "~>2.2", equivalent to ">=2.2.0 <3.0.0"

  • Require a certain version: "==1.3.0"

  • Require a minimum version: ">=1.3.0"

  • Require a version range: ">=1.3.0 <=1.3.4"

The recommended way is to use the "~>" operator. This allows flexible updates and should prevent unexpected code breakages. DUB looks up the available versions of a package in the DUB package registry at http://code.dlang.org/. The developers define the version number in their repository, for example, in GitHub. You can find more information about providing your own DUB packages in Chapter 9, Power your Application with vibe.d Extensions.

Our first application is quite simple. The application uses the main() function provided by vibe.d. This requires passing the VibeDefaultMain version identifier to the compiler. Compiler and linker switches are specified using build settings. The main() function is automatically provided if this version identifier is specified.

The use of compiler and linker switches depends on the operating system, processor architecture, and used compiler. DUB supports this with the platform attribute. The platform attribute contains the predefined platform identifiers that are converted to lower case and separated by dashes. The order of the identifiers is os-architecture-compiler. You can find the complete list in the D language reference at http://dlang.org/version.html#PredefinedVersions. Each part is optional. For example, platform="windows-x86_64-ldc" or platform="dmd".

DUB has created a small application, too. The source of the app.d module is as follows:

import vibe.d;

shared static this()
{
  auto settings = new HTTPServerSettings;
  settings.port = 8080;
  settings.bindAddresses = ["::1", "127.0.0.1"];
  listenHTTP(settings, &hello);

  logInfo("Please open http://127.0.0.1:8080/ in your browser.");
}

void hello(HTTPServerRequest req, HTTPServerResponse res)
{
  res.writeBody("Hello, World!");
}

The functionality is quite simple. As the main() function is provided by the framework, a shared static this() module constructor is used. This constructor is run at application startup before the main() function is run. In the constructor, a new HTTPServerSettings object is created. In the following two lines, the port number is set to 8080 and the IP address that the server listens to is set to localhost (IPv4: 127.0.0.1, IPv6: ::1). After that, the HTTP server is started with a call to listenHTTP(). Each request is handled by the hello() function, which only writes the string "Hello, world!" as the response.

You simply run dub in the hello folder in order to compile and run the application. DUB automatically resolves, downloads, and compiles all specified dependencies. Some of the downloaded libraries are only D bindings to the already installed libraries. For example, DUB downloads the D bindings for the OpenSSL library, which must be installed separately. If you run DUB for the first time, the tool fetches all dependencies which looks like this:

$ dub
Fetching memutils 0.4.1 (getting selected version)...
Placing memutils 0.4.1 to /home/<yourid>/.dub/packages/...
Fetching vibe-d 0.7.25 (getting selected version)...
Placing vibe-d 0.7.25 to /home/<yourid>/.dub/packages/...
Fetching libevent 2.0.1+2.0.16 (getting selected version)...
Placing libevent 2.0.1+2.0.16 to /home/<yourid>/.dub/packages/...
Fetching openssl 1.1.4+1.0.1g (getting selected version)...
Placing openssl 1.1.4+1.0.1g to /home/<yourid>/.dub/packages/...
Fetching libev 5.0.0+4.04 (getting selected version)...
Placing libev 5.0.0+4.04 to /home/<yourid>/.dub/packages/...
Fetching libasync 0.7.5 (getting selected version)...
Placing libasync 0.7.5 to /home/<yourid>/.dub/packages/...
Performing "debug" build using dmd for x86_64.
vibe-d 0.7.25: building configuration "libevent"...
hello ~master: building configuration "application"...
Linking...
Running ./hello 
Listening for HTTP requests on ::1:8080
Listening for HTTP requests on 127.0.0.1:8080
Please open http://127.0.0.1:8080/ in your browser.

Open your browser and type http://127.0.0.1:8080/ as address. You see a nice greeting from your first vibe.d application:

Tip

Downloading the example code

You can download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books you have purchased. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

Creating your first template

The sample application that is generated by DUB returns only a text string to the browser. Of course, a real web application returns HTML 5 nowadays!

The vibe.d framework includes a template engine, the so-called Diet templates. Templates are used to construct an HTML page from various reusable pieces, for example, a header and navigation bar. They also enable you to place values that are calculated in your application in the generated HTML page. You can learn about the details of templates in Chapter 2, Using Templates for Your Web Pages. For the first application, you create a template for a simple HTML 5 page.

Run dub again to create a new project:

$ dub init hello2 --type=vibe.d
Successfully created an empty project in '/<your path>/hello2'.

You can put UI related files, such as HTML pages and templates, in the views folder. Create an index.dt file in the views folder:

doctype html
html
  head
    title Greetings from vibe.d
  body
    p Hello, World!

The template syntax resembles the HTML syntax and should be understandable if you know HTML. This is a so-called static template since there are no dynamic parts involved, for example, printing the value of a variable.

Next, you need to change the generated source/app.d application to contain the following source:

import vibe.d;

shared static this()
{
  auto settings = new HTTPServerSettings;
  settings.port = 8080;
  settings.bindAddresses = ["::1", "127.0.0.1"];
  listenHTTP(settings, staticTemplate!"index.dt");

  logInfo("Please open http://127.0.0.1:8080/ in your browser.");
}

In the listenHTTP() call, replace &hello with staticTemplate!"index.dt". After that, delete the hello() function. This is all you need to do in order to use a static template!

Run dub to compile and run the application:

$ dub
Compiling diet template 'index.dt'...
 x86_64.
vibe-d 0.7.25: target for configuration "libevent" is up to date.
hello2 ~master: building configuration "application"...
Linking...
To force a rebuild of up-to-date targets, run again with --force.
Running ./hello2 
Listening for HTTP requests on ::1:8080
Listening for HTTP requests on 127.0.0.1:8080
Please open http://127.0.0.1:8080/ in your browser.

Open your browser and type http://127.0.0.1:8080/ in the address bar. You will see a similar greeting as that from your first vibe.d application. Please note that now there is a title displayed. You should also check whether the browser has received an HTML page—simply inspect the page source using facility from your favorite browser.

You may have noticed that this run of DUB was a bit faster and the output was different. The main functionality offered by DUB is the automatic resolution of dependencies. Our application lists vibe.d as a dependency. On the first run, DUB automatically downloads vibe.d. In order to find the package, DUB uses the public registry at http://code.dlang.org/. (There are many useful packages available. You will learn about the most important ones in Chapter 9, Power your Application with vibe.d Extensions. For now, just scroll through the list to get an impression of what is already available.)

The vibe.d framework itself has dependencies. DUB downloads them until all dependencies are resolved. After this step, the libraries and your application are compiled.

On every subsequent invocation of DUB, the dependencies are already resolved and the libraries are only linked with, and no longer have to be compiled. The second invocation is, therefore, faster and produces less output.

You can find the downloaded packages in your home directory in the ${HOME}/.dub/packages hidden folder on Linux or %HOMEDRIVE%%HOMEPATH%\AppData\Roaming\dub on Windows. If you delete the folder or one of the packages inside, then DUB will re-download and recompile the missing packages on the next invocation. Most importantly, you will find the vibe.d package including its source code in this folder!

DUB provides some useful options. You can see them if you pass the --help flag after the run command (the default command that is invoked if no command is given):

$ dub run --help

Two options are very useful: --force and --verbose. With --force, you can force a recompilation even if nothing has changed. The --verbose option prints diagnostic output. This can be helpful if you need to track down an error.