Chapter 1. First Steps: Getting to Know Opa

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.

Installing Opa

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!

Installing Node.js

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.

Auto-Installing MongoDB

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.

Our First Program

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.

Writing and Running the Code

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.

Our first Opa program in action

Figure 1-1. Our first Opa program in action

What localhost:8080 Means

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.

What the Code Means

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.

What Happens When We Run Your Application

When you run your application by invoking opa hello.opa --, you actually perform two different operations:

  1. You transform (or compile) the source code you have written into a runnable application.
  2. 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:

  1. 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.
  2. 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.
  3. 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.
  4. The compiler computes the data schema and generates all database queries.
  5. It then translates all client-side code from Opa to JavaScript.
  6. 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.

Details About the Opa Runtime

The Opa compiler outputs a standard JavaScript application that uses two main technologies:

  1. The Node.js framework for the runtime
  2. 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.

Toward Real Programs

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.

Battle Plan

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:

  • Declare web servers, handle requests to different URLs, and work with resources (Chapter 3)
  • Store and manipulate data in a database (Chapter 4)
  • Create user interfaces (UIs) based on the HTML and CSS web standards (Chapter 5)

But before you do that, you need to learn a bit more about Opa, which you will do in Chapter 2.

Summary

In this chapter, you got a feel for what Opa is. You learned how to:

  • Install Opa
  • Write and run a simple app
  • Set up your next goal

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.