Getting started with the Play! Framework.

Yesterday I attended Pramode sir’s workshop on ‘Introduction to developing web applications in GNU/Linux with Play framework’.

As usual, his energetic way of presenting the material got us all interested in a few seconds. Although we could not cover all the aspects in detail due to the time constraint, this post is going to be about what all he was able to teach us in the time we had together.

INTRODUCTION TO THE SESSION

So, Play! is a framework for writing web applications. What are web applications? Just like we have applications that run on our computer, they are applications that run on the web. And what are frameworks? Frameworks are those software tools that lets you use certain pre-defined functions, that implement the basic network protocols for you. So basically, you just need to concentrate purely on your application and not bother about the lower layer implementations. Hence, it is an abstraction. You can find many of them like Flask, Django, Ruby on Rails, etc.

A web applications has two parts. One, the Client side and the other, the Sever side. The Client side is where you actually see the web application in action and hence it contains our HTML, JavaScript and CSS. The Server side will run a Web Server program that gives out the matter that is to be displayed by the client. So that’s that.

Once that was explained, he got into explaining the difference between statically typed v/s dynamically typed languages. Pointing out Python as an example of a dynamically typed language, he explained the concept by the following piece of code


a = input()
if a == 1:
    a = 'Hello'
else:
    a = 1.2
print a

In the above code, we cannot determine of what data type the variable ‘a’ is at the time of printing it. Because it depends upon whether the ‘if’ or the ‘else’ executes. These kind of languages are called dynamically typed languages.

Whereas in statically typed ones, you can know the data type of variable at any given place. You can understand it better with an example C code:


int main() {
    int c;
    .....
}

When you declare a variable to be of a certain data type, that variable retains that type till the end of its scope. In this case, the opening and closing curly braces. These are called statically typed languages.

Both having their own advantages and disadvantages, there are places where both have their own uses. However, the errors in the code of a dynamically typed language will be visible only when the program is in execution and it reaches that part of the code where the error is present. Even though, static typing might not be a one that gives “error free” code, it helps you catch certain type of errors that a dynamically typed language might not be able to catch.

Then we came to the popularity of the JVM based languages these days. The popularity of such languages was based on the fact that a vast eco-system of libraries will be available at your command at the beginning itself. This is available because Java has been around for a long time and hence a lot of libraries has been developed for it. The JVM based new languages can use these and thus, move forward in full swing from the beginning itself! Clojure and Scala are the two ones that are on a roll at present.

However, both of them uses the Functional Programming Paradigm. He told us that the world was slowly realizing that OOP was not the solution to all the problems and that there were many instances where a functional approach was much better. Those days when people used to get impressed by seeing ‘Python’, ‘Django’, ‘RoR’ on your resume are behind. Now ‘Clojure’, ‘Scala’ and ‘Play!’ are those that make an impression.

During earlier days when PHP ruled the world of web application development, most applications’ code base were designed horribly. This was because all the code for a certain application was fitted into one file. As in, you would write a bit of HTML code, then insert PHP into the middle of that and then a few JavaScript here and there and finally end up making a mess out of your code, even if not your application.

In order to overcome this clumsiness, a certain design philosophy referred to as MVC (Model-View-Controller) was established and people began to follow that in order to structure their code bases better. A quick explanation of what MVC is.

Model stands for Database part of the web applications. As in, how things are stored into and retrieved from it.
View, as you might have guessed, consists of the HTML, JS and CSS. As in, what we see.
Controller defines the business logic. As in, the code that we have written using a certain language.

Now coming to play!, we were going to deal with Play!2. It seems a major difference was made in the succession from Play!1 to Play!2. The difference is that in Play!1, the core of the framework was written in Java. However, in Play!2, the entire thing has been re-written in Scala. Talking further about play!, a thing noteworthy about it is that the entire framework is statically typed! As in, at the time of compilation itself, before actually deploying the application, you will be shown the syntactical errors that you have made. According to him, this is a major (and super awesome) feature of play!.

You do not need to run your application in order to see where you have made a syntax/typing mistake. The compiling stage takes advantage of the statically typed nature of the framework, and shows you exactly the line where the error has occurred. The advantage of this is that, even though the initial learning curve might be bit high, once you get everything correct and deploy the app, the chances of it crashing are really low compared to other dynamically typed frameworks.

Another innovative feature that Play! introduced was that of automatic reloading. As in, usually when we make a change to the code in statically typed languages, we would have to compile it once more in order to run it. Play! got over that hindrance by introducing a feature that automatically detects a change in the code of the application and reloads (recompiles and reruns) it.

Now for the hands on session.

INTRODUCING PLAY!

1. Setting up play!

Always before starting a work, make sure you have the right tools for it. The first thing here would be java. Please install openjdk-7-jdk, or any versions of openjdk. They tell us not to use gcj (which is the default Java compiler on most Linux systems) as it seems to break things while execution. So to install, do:

sudo apt-get install openjdk-7-jdk

The next would be play! itself. You can download it from here. Once you have downloaded the zip file, unzip it and extract it to some location. Include that path in your PATH variable. That is, do:

$EXPORT PATH=$PATH:/path_to_play/play2.0.2/

In order to check if you are good to go, just do:

$play

and hit enter. You should see something like below:

Wonderful. Now let us proceed.

In order to teach us how to get started with it, he had already made a series of applications that took us through small step by step modifications which were really helpful in learning the concept. You can find the code base at my github repository at: https://github.com/harisibrahimkv/Play-tutorial

You can either download it as a zip from there or you can clone it. Assuming you have git and git-core installed, you can do:

$git clone git://github.com/harisibrahimkv/Play-tutorial.git

which will clone the repository for you.

2. Creating your first app

In order to create your first app, do:

$play new app (you can give any name here and not necessarily ‘app’)

You will be asked your app name and also the template you wish to choose. See the figure below:


Now, play! will have created a pretty good working application skeleton for you in a directory called app. If you ‘cd’ into it, you will be able to see 4 folders and a README file. This is the basic structure of any play! application. In order to create your application, you just need to fill in whatever you want. Let us try running the app huh?

3. Running your first app

Alright. Just do:

$play

and hit enter. Now you will see your memory and processor being eaten up! It will take a while before the application starts working. However, this seems to be the case in development mode only. A deployed play! 2.0 app is not that memory intensive.

Once it is done, you will be given a prompt. Type “run” there and hit enter. Once it says “Server started”, you are good to go. Access your browser and head over to:

http://localhost:9000/

It will take a while for the page to load as the code only starts to compile once you send the server a request. This is the case only in development mode. While in production mode, compilation will be done beforehand itself. See the web page loading? Wonderful. Do not try out anything written in that page for now. Let us proceed with Pramode sir’s example. Your terminal will be looking something like this now:

In order to stop the program, hit Ctrl+c.

Just a quick explanation of the different folders:

app: This contains your application. If you cd into it, you can see the sub folders ‘controllers’ and ‘views’. Inside ‘controllers’ you will a ‘Application.java’ file, which is the code that you write. It will be already filled with a basic application. The ‘views’ folder is where your templates go. What are templates? Templates are files that contains HTML code. But it is not purely HTML. You can write Scala code in a template thereby allowing you to use features like “for loops” and “variable declarations” inside it. Usually, the “models” sub folder should also be present here. But there is no need for a database for a minimal application. Refer to the figure below:

conf: The conf directory contains two files. A ‘application.conf’ file and a ‘routes’ file. We did not cover what the former one was for. But the latter one is the important one for now. The ‘routes file specifies which function in your /app/controllers/Application.java file should be triggered corresponding to a given URL. You’ll understand this better once we go the tutorial.

project: It contains the play build tool called sbt (Simple Build Tool). Much like the Makefiles we use. We did not concern ourselves with that.

public: This contains the images used in the web app, the javascript codes and the css scripts.

Now, get into the ‘part1’ folder which you cloned from my github repository earlier. We will walk you through all the steps one by one.

4. Through the Tutorial

This tutorial is aimed at providing a basic idea about how the play! framework works. It does not include explanation of the syntaxes of neither Java nor Scala. Hence, if you know either of those two, you’ll be able to improvise quickly. Otherwise, you will have to learn them. During the workshop, we were only able to go through ‘part1’ of the entire tutorial. ‘part2’ was covered only vaguely.

How we move about in the tutorial is by visiting the folders of each app, checking the README there, then the /conf/routes file, the /app/controllers/Application.java file and to the end, the /app/views/index.scala.html file.

We first go into the folder ‘part1’ and explore the different ‘app*’ folders there.

app1

This is the same one that we made ourselves earlier by creating our first app. Hence we won’t look into it further.

app2

Remember the flow, the README file, then the /conf/routes file and so on. This app is to show the most fundamental idea of how a play! app works. We can see in the ‘routes’ file that there is a “GET / controllers.Application.index()” line. What does it mean?

That line defines the rule that, if ever a “GET HTTP” request comes that corresponds to ‘/’ (In a URL, simply a / denotes the domain name itself. As in ‘google.com/’, ‘facebook.com/’, etc. Note the trailing slash at the end of both the domain names), then the function “controllers.Application.index()” should be executed. In case you haven’t already figured out, that functions resides in the file “/app/controllers/Application.java

You can see the method index() there with a “return” statement in the body. The “ok”, it seems is an object that everything is fine in the execution of the code, and the plain text “Hello, world, again!” maybe sent to the client. Since it is simply passed as a string, it will be displayed as plain text in the browser.

Now try running the app as we said before in the “Running your first app” section. However after typing in”play” and you are given the prompt, do not directly type “run”. This is because the code you cloned from my repository at github has been run by me once. As such, the class files will be present already in the application. First remove them and then “run” your application. In order to remove the class files, type in “clean”.

Now “run” and head over to “localhost:9000” (our domain name in this case) in your browser where you should be able to see the plain text “Hello, world, again!” displayed.

Mind you, run the command “play” from within the directory that contains the “app”, “conf”, “projects”, “public”, etc folders.

Got it? Cool. Let us proceed soldier.

app3

It is time to add more URLs. Check the README and then the “routes” file. You can see that two more URLs are defined. Things that come after the first ‘/’. You have seen “facebook.com/user” right? Similar to that. Two new functions are mentioned in the  “routes” file. So check them out in the Applications.java file.You can see those functions defined.

Try running the code. If you head over to “localhost:9000”, you will be greeted by the return value of the index() function, if you check out “localhost:9000/docs” you will be greeted by the return value of the docs() function and correspondingly for “fun” too.

That was easy now, wasn’t it? Let us move on.

app4

README. Don’t forget the flow in each app.

We are introducing an error into the “routes” file. Instead of giving the function name as docs(), we are giving it as doc(). It is a common mistake that could happen to anyone. The point that you should understand here is that, since this is a statically typed framework, everything is checked for consistency beforehand. So in production code, even before you run the app, you will be shown the error which, according to him, is a great feeling of relief while switching from dynamic ones to static. However, since we are running development code, the compilation will be done only once you have sent the URL. Hence, we might feel no difference yet.

Try running the application (don’t forget to run “clean” at the prompt) and go to “localhost:9000”. You need not go to /docs to get the error because the compilation is done once you have activated the first URL itself. You will be greeted by a friendly, cool looking error message in the browser. Do NOT look into the terminal! It will be shouting at you with a lot of stuff. Don’t be scared and don’t be discouraged. Did you get the error message in your browser? Awesome. Forward March!

app5

We are simply playing with the syntax of the definitions in routes. Instead of the URL /docs, we are giving /docs/one. Now if you run the app and check out “loalhost:9000/docs/”, you will get an “Action not found” error message. In order to invoke the docs() function, you have to type in the defined URL “/docs/one” itself.

Let’s move on.

app6

Continuing with testing the syntax of URLs, suppose you want to pass a variable to your web application through your URL. How would you do it? We see that now.

In the “routes” file, you can see that the /docs/ is followed by a “:num”. This states that whatever comes after /docs/ in the URL that you specify, it will be treated as variable with the name “num”. The type of the parameter is specified in the argument part of the corresponding function. You can see that in this case, it is “num: Long” which is of integer type.

Check out the corresponding function definition at the Applications.java file. You can see that the docs() function is receiving ‘n’ as a parameter and you can use it inside your ‘return’ statement as give there.

Now try running the app and checkout “localhost:9000/docs/37” in your browser and see the magic working. Got it? Let’s keep pushing my men!

app7

Suppose you make a mistake in declaring the type of your URL parameter. What happens then? You can see that the ‘routes’ file is same as before. But checkout the /app/controllers/Application.java file. In there you can see that the parameter has been declared as a String. So there is a type mismatch.

Try running the app and head over to “localhost:9000”. You will be greeted by our good old friendly and cool erro message. As before, don’t look at the terminal lest you should black out. Check the browser. You will see:

Saw it? Then let’s get going.

app8

What if we want to pass two URL parameters to the application? That is what this app demonstrates. In the “routes” file, you can see that there is a rule /:student/:mark. So you can specify two parameters after “localhost:9000”. No, you MUST specify two parameters after “localhost:9000” if you want the second rule to be invoked. If you pass just one parameter in the URL, you will receive an “action not found” error. If you pass the parameters in wrong format, as in if you give a string instead of marks, you will get a “bad request” error too.

If you check the corresponding Applications.java file, you can see that we can use the parameters passed as we like. In the corresponding evaluate() function, we care comparing the marks with 80 and executing one of the statements based on the comparison. Try running the app. Experiment with passing marks less than 80 and greater than 80. Feel the difference! Your URL can be something like “localhost:9000/wolverine/67”.

Felt the difference? Excellent. The end is in sight, let’s move on.

app9

Now we come to query strings. You can read upon what query strings are here. If you check the “routes” as well as the Application.java file, you can see that we don;t have to do anything special in order to make the application accept a query string. All we have to do is to put an extra parameter in the function definition. In this case, that is “mark: Long”. Once that is there, we can pass query strings to the applications as follows:

“localhost:9000/wolverine?mark=35”

Try running the app and check it out with the above query string or with one of your own. Gave enough marks to wolverine? Great. Next one!

app10

Till now, we have only displayed plain text in out browser. But as you all know, it rarely the case that you get to see plain text in websites. Almost all the content is of HTML type. So how do we display HTML? Let us get to it.

This is where the “views” folder under /app/ comes into life. We had explained earlier that the “views” folder would contain the templates. Templates are not purely HTML. But for this example, we use a purely HTML template.

Check out the HTML code at /app/views/Application/hello.scala.html . It is a straightforward code and you can understand how it will be displayed in the browser. How is it displayed? Whenever we use the /hello URL, the corresponding function hello() in Applications.java file get executed. It returns a function (views.html.Application.hello.render()) value. That “hello” in that string is the name of our HTML file in the “views” folder. We named out file hello.scala.html right? That .scala.html extension should be there for all the templates.

Try running the code and visit “localhost:9000/hello” to view your first HTML output using play! in your browser.

Happy? Pat your back but no time to wait! Let’s keep going.

app11

How do you pass variables to your template in order to display them as HTML in your browser? The “routes” file is the same. We pass a parameter through the render() function that we saw above. Check the Applications.java file and you can see that render() has a parameter “Arun”. Alright, we understand how to pass an argument to functions, but how is it possible to get that variable in an HTML file? That is why we said that we are using “templates” and not HTML files. The templates here can contain Scala code in it.

So, checkout the template under app/views/Application/hello.scala.html

You can see that the first line is “@(name: String)”. This is the part that accepts the argument that we passed through the function into the template through a String variable “name”. Now, the template will replace wherever it sees “@name” in that file with the parameter passed, in this case “Arun”.

You don’t believe me? Then try running your app and visit “localhost:9000/hello”.

Ah ha! Now you believe me right? Hmph! Next..

app12

Now we couple two things that we learned above. Passing a parameter to the application via a query string and then passing that variable to the template in order to display it as an HTML output. So you can see that we have declared a parameter for the hello() function in the “routes” file. Now you can pass a query string such as “localhost:9000/hello?name=wolverine”. So “wolverine” will be there in ‘name’.

Then the hello() function in the Applications.java file is invoked. There, it has a parameter name, which will now contain what we passed. We use that parameter in the render function and thus, pass it to our template. The template is the same as last one and accepts the passed argument into “@name”.

Run the application and try passing the above URL. Greeted Wolverine? Swell! Now for the final app of part1!

app13

Here we learn to send multiple items through a query string parameter, to split those items and finally display them as a bullet list HTML page.

The “routes” file does not have anything new. It just accepts a String variable called “namelist” which is passed to it as a query string. The corresponding hello() function in Applications.java is invoked.

In the hello() function, we declare an array of strings (String t[]) and pass it the query string values (now in “names”) one by one by splitting them at the commas. Once we finish doing that, we pass the array “t” into the render() function to be accepted by our template. Now let us take a look at our template.

Check the app/views/Application/hello.scala.html file. We can see that it accepts the array ‘t’ that we passed into an array of Strings called names. This is what the “@(names: Array[String]) does. Now, since “names” is an array, we need to take each element from it individually right? That is what that funky looking “for loop” does.

The “@for(name <- names)” iterates over the array “names” and assigns each string in the array into the variable “name”. This is displayed as a list by the “@name”. So, basically, that for loop pastes that contents of the array into the file as an HTML code and then our render() function renders and return it to the browser.

Try running the app and pass the following URL in the browser:

“localhost:9000/hello?namelist=wolverine,haris,batman”

Saw all the superheroes being listed? I know you did. Thank you!
———————————–

This concludes part1 of the tutorial. We did not get enough time to discuss part two entirely. Hence I will share what I know.

One of the most important parts of a web application is the Database part. MySQL is one of the most popular relational Database models. However, here he mentioned about ORM – Object Relational Mapping. ORM is a programming technique that is used to convert a relational database into an Object Oriented model with the first field as the object and the rest of the fields (columns) as their attributes. But it seems that this abstraction is a leaky abstraction.

Leaky abstraction refers to those abstractions that fail to let us use that abstraction without knowing what happens underneath it, at some point of time. As an example, in Python, he told us to try inserting elements at the beginning of a list as well appending at the end of a list. When you try the above two approaches with a million items, you  will find that the former one takes a heck lot of time than the latter. In order to understand why this happens you will need to dig into how lists are implemented in Python using C. Hence, what lies beyond will be revealed, piercing the abstraction.

Refer to the following article for a hilarious description of the Law of Leaky Abstractions:

http://www.joelonsoftware.com/articles/LeakyAbstractions.html

Now enter into the folder ‘part2’ and let us explore the ‘app*’ there.

app1

Up until now, all that we have done are GET requests. GET requests are those HTTP requests that do not change the state of the server program and the database. It simply requests a resource which the server sends back to the browser. By default, all the URLS in a browser are GET requests. On the other hand, a POST request is what we use in order to change the state of the server side program and database. But how can we invoke a POST request if the browser sends all the URL as GET request by default? Let us see.

If you check in the ‘routes’ file, you will find that a new rule has been added. “POST /add additem()”. In order to test whether the function additem() works, we need to send a POST request with the URL /add. We cannot directly type in a POST request in the address. So we use a command called “telnet” to test our application. First of all, run our app. Once it has started running, and you see the “Server started” message, open a new terminal.

Install telnet on your system. It must be there by default on Ubuntu systems. Type in:

$telnet localhost 9000

and hit enter. You will see a few messages and then the cursor will stay below it, blinking. Type “POST /add http/1.0” and hit enter twice. You will see the return statement of the additem() function printed on your terminal. Refer to the following figure. After running the application in one terminal, in the other terminal:

That highlighted line is what you should type in and HIT ENTER TWICE. So our application is working in receiving POST requests and in responding to it. Let’s get to app2.

app2

Here we see how we can trigger a POST URL from our browser. For this purpose we create a “form” in HTML. You can see that the ‘routes’ file has not been changed. However, the index() function in ‘Applications.java’  renders a template called ‘index’. Let us take a look at that template under /app/views/Applications. The ‘index.scala.html’ file.

If you know basic HTML, you can understand that we are creating a form, which is a submit button, whose action is ‘/add’ and method is POST. Thus, if you click that submit button, it will ivoke the URL ‘/add’ with a POST request, which, according to our ‘routes’ file, will trigger the additem() function.

Try running the app and visit “localhost:9000”. You’ll be able to see the “submit” button. Click on it and you can see the additem() function getting invoked.

Cool? Let us proceed.

app3

This is where you actually POST some data and the server responds according to the data you have posted. However, by this time, the session was at an end and we could not discuss in depth what was going on.

First of all, the index.scala.html file is rendered which gives you a text box named “task” along with a “submit” button. When you type something in the box and hit “submit”, that data will be sent as a POST request on /add. Thus the function additem() will be invoked. That function extracts the data we sent and stores it in a String called ‘task’, and then sends back the response as plain text which includes the “task” String.

Try running the application. Enter something and hit the “submit” button. You will see the String under the additem() function being printed on your browser appended at the end with the task that you entered. So now you know how to issue a POST request.

—————————

Unfortunately, we did not have time to discuss the further applications. We directly went to app6 and tried running that app to see the output. With that, the session came to an end.

A small discussion was there regarding how sessions were established. He explained that each HTTP request is independent from other HTTP requests. Hence it has no way of identifying whether the requests are coming from the same user. So the concept of session is done by implementing cookies. What are cookies? When a user “logs in” to a website, that site sends with the response of the user’s request, an exclusive data that will be stored temporarily in the user’s computer. When making the next request, if the user has not logged out, his browser will take this data and send it along with his HTTP request. When the Server sees this exclusive data, it understand that the new request comes from the same user itself. This is how sessions are established.

The session came to an end with us having a few friendly chats. It was a really informative and practical workshop. One ofthe best ones that I have ever attended. Hoping for more in the future!

Let’s play!

Advertisements

2 thoughts on “Getting started with the Play! Framework.

  1. Pingback: Getting started with the Play! Framework. « A 'psycho' path. | playframework | Scoop.it

  2. Pingback: Getting started with the Play! Framework. | #Play! #Scala in #PaaS and in #Hadoop | Scoop.it

Hey! What do you think? Share your thoughts. :)

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s