In this chapter, you will get your first glimpse of Opa. You will learn how to install it, write an Opa program, and become familiar with the crucial steps in the development cycle.
To install Opa, get the package for your architecture from Opa’s website. At the time of this writing, installers are available for all major platforms: Mac OS X, Windows, Linux (generic, Ubuntu, and Fedora), and FreeBSD. These installers work with 64-bit architectures and, on some platforms, with 32-bit architectures.
On Mac OS X, you need to have Apple’s Xcode command-line tools installed as well.
As an option, you can compile Opa from source, but we strongly recommend using packages to begin with.
Once you have downloaded Opa, you can that check it’s correctly installed by opening a terminal and running the following:
Tokyo:~ henri$ opa --version Opa compiler (c) MLstate -- version 1.0.7 -- build 4040
This gives you the Opa version and build number. Opa then checks that its runtime dependencies are also installed in your system and should guide you to install them if necessary. You are all set!
Opa uses Node.js to execute JavaScript code on the server. To install Node.js, get the package for your platform from the Node.js website. Then type the following command in your terminal:
Tokyo:~ henri$ npm install -g ursa formidable
The -g
stands for global
and means that the node modules will be installed wherever the Node.js program could easily find them.
MongoDB is automatically installed and launched while you are running the Opa application on the server.
Note
You can find up-to-date installation instructions online at https://github.com/MLstate/opalang/wiki/Getting-started.
In this section, you will write and then run your first program. You’ll then learn what the code actually means, how to build the application, and what happens behind the scenes.
You will write your Opa application code in a text editor. Any basic editor works, but we recommend using one of the editors for which Opa-specific plug-ins exist, including:
Please check the online Opa documentation for up-to-date information on how to set up your preferred text editor.
Now open your editor and create a file that is named hello.opa and that contains the following content:
Server
.
start(
Server
.
http,
{
title:
"Hello, world"
,
page:
function()
{
<h1>Hello, world</h1>
}
}
)
This is a very simple application that just displays a static Hello, world
message. You can run the application by typing the following command in a terminal:
Tokyo:~ henri$ opa hello.opa --
Http serving on http://localhost:8080
We will come back to this code later to discuss what actually happens here. For now, just point your browser to http://localhost:8080 and you should see something similar to Figure 1-1.
Usually, you open addresses in your browser that look like this: facebook.com. This so-called URL (Uniform Resource Locator) allows to locate Internet resources, similar to how you use street addresses you to locate buildings.
Referring to the URL used in the preceding code, localhost is the standard way to address the local machine, that is, this computer. The corresponding IP address, usually 127.0.0.1 or the name of your computer, will work as well.
The 8080 after the colon in the address is the port number. Domain names are used to locate sites; ports are used to distinguish different services within sites. If we were to compare URLs to street addresses, domain names would correspond to the country, city, and street, whereas the port would correspond to the house/apartment number.
The default port for web services is 80. However, running applications on
port numbers smaller than 1024 often requires administrator rights; therefore,
Opa chooses 8080 as the default port for its applications. You can change
this with the --port X
switch of the executable; for example:
Tokyo:~ henri$ ./hello.js --port 2012
Lastly, a URL may also contain a path, as in http://example.com/this/andthat.html, in which the path is /this/andthat.html. The domain name and the path are handled separately. The domain name is used to locate the box running the service. To do this, browsers make requests on DNS servers that translate the name into the IP address of the service. When scaling, the DNS is the first technology to distribute the requests of many clients to different boxes. The path is used to locate a resource on the service. Originally, the path was used to locate a file on the service—perhaps a static resource such as an image or a script. But with modern frameworks such as Opa, most resources are virtual.
Let’s decipher the meaning of the four lines of code we wrote:
Server
.
start(
Server
.
http,
{
title:
"Hello, world"
,
page:
function()
{
<h1>Hello, world</h1>
}
}
)
Server.start
is an entry point for Opa programs, much like main
in Java or C, which launches the application web service. It takes two arguments: the server configuration and the definition of
how the server should handle incoming requests. This second parameter can exist in many different forms, and you will learn more about them in Chapter 3.
Here we are using a variant that creates a simple application with a single page (which will be
shown regardless of the URL). This variant is defined by a record with two fields: title
and page
, denoting the page title and content, respectively. If you are familiar with JavaScript, you will notice that Opa borrows the same { field1: val1, ... fieldN: valN }
syntax to denote
records. You will learn more about records in Records.
The title
field is a string
, whereas page
is a function that takes no arguments and returns the (X)HTML content of the page.
Note
HTML stands for HyperText Markup Language and is the standard markup language for web pages. If you are not familiar with it, we suggest that you grab a good book or some of the multitude of online resources on HTML.
HTML is a first-class citizen in Opa: it is a predefined data type with special support that allows it to be entered using its usual syntax. Opa supports the shiny and new HTML5 version of HTML. You will learn more about HTML5 features in Chapter 5.
When you run your application by invoking opa hello.opa --
, you actually perform two different operations:
- You transform (or compile) the source code you have written into a runnable application.
- You launch the runtime environment and execute your application.
Let’s take a closer look at step 1. Opa is a JavaScript framework consisting of two pieces: a library and a compiler. The library is an approximate version of the prebuilt code you use in your applications, while the compiler is a strange and complex beast that performs several operations:
- The compiler reads the Opa code you have written (that step is called parsing) and checks that the code is syntactically correct. For instance, if you forget a closing parenthesis in your code, you will get a parsing error.
- If parsing succeeds, the compiler verifies more deeply that your application does not do silly things, by checking the consistency of the whole application. This major step is called typechecking and you will learn about it in detail in Chapter 2.
- If typing succeeds, the compiler identifies which parts of the application run on the server, on the database, and on the client. This step is called slicing and it is one of the unique features that Opa provides.
- The compiler computes the data schema and generates all database queries.
- It then translates all client-side code from Opa to JavaScript.
- Finally, it generates the Opa server-side code to JavaScript code (with the Node.js backend) and embeds the client resources (including the generated client code) so that the server can send them to any client that connects.
Of course, you don’t need to know exactly how the Opa compiler works to develop applications. Several development environments (or IDEs) have integrated project build capability, so the compilation process is just a keystroke away.
Throughout this book, we will show you how to work with Opa using the command line, since it works repeatably on all platforms. IDEs are just graphical interfaces for running the same commands for you.
If there are any problems, the compiler will inform you of them with appropriate error or warning messages. Otherwise, an executable JavaScript file will be generated. In this case, it will be called hello.js.
The Opa compiler outputs a standard JavaScript application that uses two main technologies:
- The Node.js framework for the runtime
- The MongoDB database
Opa-generated apps check that their own runtime environment is correct—that is, that your system is properly installed—so both should be set up by now. If not, check Installing Opa.
You can compile a program without running it by invoking:
Tokyo:~ henri$ opa file.opa
without the double minus sign.
If you look at what happened in your directory, you will see that Opa creates one file and one directory:
Tokyo:~ henri$ ls
_build program.js program.opa
The program.js file is the one you can run by invoking:
Tokyo:~ henri$ ./program.js
Http serving on http://localhost:8080
The _build directory contains the resources of the generated application. The application that results is a standard Node.js/MongoDB application that you can deploy in the cloud.
If some Node.js packages are missing, Opa will guide you through installing them when running your application:
Tokyo:~ henri$ opa file.opa
--> some node modules are missing, please run: npm install mongodb formidable nodemailer imap
Note
The cloud platform that most startups use, Amazon EC2, plays nicely with Opa. Go to https://github.com/MLstate/opalang/wiki/Amazon-Image-for-Opa for more information. Another interesting option is to use an online platform (a concept also called Platform-as-a-Service, or PaaS) on which you can deploy your application code directly. Platforms such as dotCloud and Heroku support Opa. Please consult https://github.com/MLstate/opalang/wiki/Opa-in-the-Cloud for up-to-date instructions for each platform.
In our short “Hello, World” application, all the code went into a single hello.opa file. For real programs, you’ll want to split the code among different files.
For instance, the popular MVC (Model-View-Controller) approach is to separate three things in an application: the model, which represents the data and its treatment; the view, which is the user interface of the data; and the controller, which synchronizes the model and the view.
It’s very easy to start a new application with Opa thanks to a scaffolding mechanism that automatically creates an empty MVC application for you. Just type:
Tokyo:~ henri$ opa create myapp
OpaCreate: Generating myapp/Makefile...
OpaCreate: Generating myapp/Makefile.common...
OpaCreate: Generating myapp/opa.conf...
OpaCreate: Generating myapp/resources/css/style.css...
OpaCreate: Generating myapp/src/controller/main.opa...
OpaCreate: Generating myapp/src/model/data.opa...
OpaCreate: Generating myapp/src/view/page.opa...
Now you can type:
$ cd myapp $ make run
to create a myapp
application.
You can compile it and run it using the following command:
Tokyo:~ henri$ cd myapp; make run
To see the source of the application, take a look at the generated files and open main.opa, data.opa, and page.opa with your favorite editor:
Tokyo:~ henri$ ls -R src
controller model view
src/controller:
main.opa
src/model:
data.opa
src/view:
page.opa
We will discuss the code in Chapter 2, but for now it’s important to know the following:
- The controller main.opa is the main file of the application, much like hello.opa was.
- The model data.opa is almost empty and contains a sample database declaration.
- The view page.opa is mostly static HTML content.
Now that you have written your first Opa application, you are ready to proceed with the main goal of this first part of the book: creating a simple wiki app. Our high-level specification for the app is as follows:
- The app should support the popular Markdown markup format.
- Different topics should correspond to different URLs.
- Editing should be inline, with an easy way to switch between viewing and editing modes.
- It will be rather simple: no preview (in editing mode), no index, and no user and history management (i.e., everyone can edit pages, and the app will not store previous versions of pages, nor information about who made the modifications).
The application is not overly complicated, but it still has a number of interesting features that will give you a great opportunity to learn how to tackle different issues in Opa. In the following chapters, you will learn how to:
But before you do that, you need to learn a bit more about Opa, which you will do in Chapter 2.
Get Opa: Up and Running now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.