• Aucun résultat trouvé

Client-server Web applications with Ocsigen

N/A
N/A
Protected

Academic year: 2021

Partager "Client-server Web applications with Ocsigen"

Copied!
4
0
0

Texte intégral

(1)

HAL Id: hal-00691710

https://hal.archives-ouvertes.fr/hal-00691710

Submitted on 26 Apr 2012

HAL is a multi-disciplinary open access

archive for the deposit and dissemination of

sci-entific research documents, whether they are

pub-lished or not. The documents may come from

teaching and research institutions in France or

abroad, or from public or private research centers.

L’archive ouverte pluridisciplinaire HAL, est

destinée au dépôt et à la diffusion de documents

scientifiques de niveau recherche, publiés ou non,

émanant des établissements d’enseignement et de

recherche français ou étrangers, des laboratoires

publics ou privés.

Client-server Web applications with Ocsigen

Vincent Balat, Pierre Chambart, Grégoire Henry

To cite this version:

Vincent Balat, Pierre Chambart, Grégoire Henry.

Client-server Web applications with Ocsigen.

(2)

Client-server Web applications with Ocsigen

Vincent Balat

Univ Paris Diderot Sorbonne Paris Cité PPS, UMR 7126 CNRS, Inria Paris, France

vincent.balat@

univ-paris-diderot.fr

Pierre Chambart

CNRS, PPS, UMR 7126 Univ Paris Diderot Sorbonne Paris Cité

Paris, France

pierre.chambart@

crans.org

Grégoire Henry

CNRS, PPS, UMR 7126 Univ Paris Diderot Sorbonne Paris Cité

Paris, France

gregoire.henry@

pps.univ-paris-diderot.fr

ABSTRACT

The Ocsigen framework offers a new way to develop sophis-ticated client-server Web applications. It makes it possible to write as a single program both the server and client sides of a Web application, thus simplifying a lot communications and data transfers, and avoiding code duplications. It also proposes a wide set of high level concepts to program tra-ditional Web interactions in a very concise way while mix-ing them seamlessly with client side features. The use of a powerful type system improves a lot the reliability of pro-grams, reducing debugging time, and making the code easier to maintain.

Categories and Subject Descriptors

D.3.3 [Software]: Programming languages—Language Con-structs and Features; H.5.3 [Information Systems]: In-formation interfaces and presentation—Group and Organi-zation InterfacesWeb-based interaction

General Terms

Languages, Reliability

Keywords

Continuation-based Web programming, AJAX, Javascript

1.

INTRODUCTION

Recent Web browsers have become powerful virtual ma-chines in which more and more programs are executed. Desk-top programs are currently being superseded very quickly by ever more sophisticated cloud applications.

Today, most Web developers are using distinct languages for programming traditional Web interaction (e.g. forms, ∗Work partially supported by the French national research agency

(ANR), PWD project, grant ANR-09-EMER-009-01, and performed at the IRILL center for Free Software Research and Innovation in Paris, France

Copyright is held by the authors/owner(s).

WWW2012 Developer Track, April 18-20, 2012, Lyon, France.

links and bookmarks) and client side features. This creates an impedance mismatch that often requires explicit data conversions and code duplications, all of which being error prone. For instance, data validation should be performed typically both on the client for early feed-back and on the server for safety. This approach also makes it difficult to combine in a flexible and natural way client and server fea-tures. As a result, client features remain often restricted to small one page applications with no persistence when links are followed.

Even though there are good libraries that attempt to ad-dress these problems, we believe that rethinking program-ming tools could speed up the rise of applications taking full advantage of the new possibilities offered by modern browsers.

A few programming frameworks now propose to use the same language both client and server side [4, 7, 2]. On the client, they must rely on what browsers provide, that is, basically Javascript. The good news is that there now exists good and fast Javascript engines, available on servers as well [5].

The Ocsigen project [1] takes the alternative approach of using Javascript as the target language of a compiler. In-deed, we want to use advanced language features not avail-able in Javascript. The goal is to abstract away technical details, proposing high level technical concepts correspond-ing closely to the very needs of Web developers. This makes it possible to express sophisticated behaviors in very few lines.

One of the most powerful features of Ocsigen is the way Web interaction, such as the effect of following links, is pro-grammed through a unique concept of “services”, and re-mains automatically compatible with client side features: the client side program persists while the user browses the Web site, and traditional features like bookmarks, forms, sessions or “back button” automatically remain available, in a transparent way.

Finally Ocsigen is making extensive use of the powerful type system of the underlying language, OCaml, to detect at compile time many programming errors. For example it makes it impossible to generate invalid HTML. All this reduces a lot debugging and testing time!

We start in section 2 by showing an example of application written with Ocsigen. Section 3 shows the basics for writing a client-server application as a single program, whereas the way to program traditional Web interaction is sketched in section 4. Then, section 5 shows how we benefits from static typing.

(3)

2.

EXAMPLE

Figure 2 shows the full source code of a client-server draw-ing application (see also a screen-shot in figure1, and a work-ing version at URL http://ocsigen.org/graffiti). This program allows the user to draw on the screen, choose the color of the brush, and see in real time what other users are drawing.

We won’t go into the full details of the code, which is basically plain OCaml. For more explanations, there is a tutorial showing step by step how to write this program at URL http://ocsigen.org/tutorial.

The first thing to notice is that the code is short. And this is due not to the use of specialized libraries that would do everything for us (we are using a library only for the color picker) but rather to the expressiveness of concepts.

As you can see, the code is divided into several parts with special bracket to distinguish between client code, server code, and shared code. It mainly defines one service, corre-sponding to a URL and returning an HTML5 page, together with some code to be executed once the page is loaded.

Figure 1: The Graffiti program with two windows

3.

CLIENT SERVER WEB APPLICATIONS

3.1

General principles

Writing client and server code together brings many ad-vantages beside the use a single language. It allows a seam-less communication of data between both parts of the pro-gram. Server side variables can be used from the client (see line 37); their values are sent along the page. This also en-sures that client and server codes remain consistent. For instance, in this example, if the color of the brush were re-moved from the messages sent on the bus (on line 33), the compiler would complain if the remaining of the code were not updated accordingly, and it would point to the location of the error.

Interfaces are built in the usual declarative way, and sent together with the code corresponding to dynamic parts. Pro-grams are written in way very similar to desktop applica-tions. For example a very simple interface allows to use user variables server side as if there was a single user program.

3.2

The Js_of_ocaml compiler

The client side code is translated from OCaml to Javascript by the Js of ocaml compiler. A syntax extension makes it possible to directly invoke Javascript methods (line 23), set object properties (line 19) or create objects (line 22). This makes it easy to bind Javascript libraries (like Google Clo-sure in our example [3]). Appropriate types can be used to ensure that objects are not misused. The compiler performs dead code elimination. Hence, the programmer does not have to restrict himself to minimal libraries.

3.3

Persistent client side programs

Ocsigen allows to combine the best of traditional and persistent applications. It is possible to write persistent applications in a classical declarative way. Only the reac-tive parts involves using DOM interfaces. This way, users with Javascript disabled and search engine crawlers can still browse the site and pages have real bookmarkable URLs.

When loading a page, links and forms are modified such that clicking links appears to work as usual, but does not in fact interrupt the Javascript program. This feature makes it possible to write very easily applications that need to keep a state during the navigation, such as an audio library with a music player, or persistent widgets (ex. a chat).

Having these features with other frameworks usually re-quires code duplication to implement a Javascript-less ver-sion of the site.

4.

SERVICE BASED PROGRAMMING

Programming traditional Web interaction is done through the notion of service. A service is a kind of function invoked in reaction to an HTTP request, and that usually returns a Web page. Main services are identified by the URL they are attached to. Ocsigen proposes many other ways to identify a service: based on special parameters, on the HTTP method, on the names of parameters, on the current session, etc.

As an example, suppose you want to implement a login box on each page of your Web site. If a user logs in from a page, you want him to remain on this page after connection. With Ocsigen, you just need to create an extra service, not attached to a precise URL (that is: available from any URL), and that will perform the action of checking the password and registering session data. This only takes a few lines of code.

Another very convenient feature is the ability to dynam-ically create new services, for example services customized to one user and that depend on previous interactions with him. This simplifies a lot programming sequences of pages, each depending on the previous ones (like buying a plane ticket). This is usually known as continuation based Web programming[6].

5.

STATIC TYPING

Simply put, static typing is the principle of verifying at compile time that values are correctly used. It can provides some basics properties like ensuring that variables are de-clared and initialized. But, when the type system is powerful enough, it can also protect against more complex program-ming errors. With a powerful type inference mechanism, type safety can be combined with the lightweightness and flexibility of dynamic languages.

In Ocsigen we leverage the power of OCaml type system to enforce many properties at compile time. We can for in-stance ensure that Javascript APIs are correctly used, that database accesses are safe, that links go to existing services with the right parameters. With the whole application writ-ten as a single code base, we can moreover ensure that com-munications between client and server can’t go wrong.

One of the most impressive use of static typing in Ocsi-gen is for checking at compile time the validity of function generating HTML. This makes it impossible for an Ocsigen program to generate a page that does not respect the W3C recommendations!

(4)

1 { shared { (* Code s h a r e d by c l i e n t and server , d e f i n i n g c o n s t a n t s and the type of m e s s a g e s *) 2 let width , height = 700 , 400

3 type m e s s a g e s = ( string * ( int * int ) * ( int * int )) d e r i v i n g ( Json ) 4 }}

5

6 let b = E l i o m _ b u s . create ~ name :" g r a f f " Json .t < messages > (* The bus used for c o m m u n i c a t i o n *) 7

8 { client {

9 let draw ctx ( color , ( x1 , y1 ) , ( x2 , y2 )) = (* C l i e n t side f u n c t i o n for d r a w i n g on a c a n v a s *) 10 ctx ## s t r o k e S t y l e <- ( string color );

11 ctx ## b e g i n P a t h (); ctx ## moveTo ( float x1 , float y1 ); ctx ## lineTo ( float x2 , float y2 ); ctx ## stroke () 12 }}

13

14 let m a i n _ s e r v i c e = M y _ a p p l . r e g i s t e r _ s e r v i c e ~ path :[" "] ~ g e t _ p a r a m s : E l i o m _ p a r a m e t e r s . unit

15 (fun () () -> (* The main service , at URL "/" , with no p a r a m e t e r *) 16 onload (* p i e c e of code to be e x e c u t e d in the b r o w s e r a f t e r l o a d i n g the page *) 17 {{ let canvas = D o m _ h t m l . c r e a t e C a n v a s D o m _ h t m l . d o c u m e n t in (* the c a n v a s *) 18 let ctx = canvas ## g e t C o n t e x t ( D o m _ h t m l . _2d_ ) in

19 canvas ## width <- width ; canvas ## height <- height ; 20 Dom . a p p e n d C h i l d D o m _ h t m l . d o c u m e n t ## body canvas ; 21

22 let pSmall = jsnew Goog . Ui . h s v P a l e t t e ( null , null , some ( string " goog - hsv - palette - sm ")) in

23 pSmall ## render ( some D o m _ h t m l . d o c u m e n t ## body ); (* the c o l o r p a l e t t e *) 24

25 let x , y = ref 0 , ref 0 in (* c o m p u t i n g c o o r d i n a t e s *) 26 let s e t _ c o o r d ev =

27 let x0 , y0 = D o m _ h t m l . e l e m e n t C l i e n t P o s i t i o n canvas in 28 x := ev ## c l i e n t X - x0 ; y := ev ## c l i e n t Y - y0 in 29 let c o m p u t e _ l i n e ev =

30 let oldx = ! x and oldy = ! y in 31 s e t _ c o o r d ev ;

32 let color = t o _ s t r i n g ( pSmall ## g e t C o l o r ()) in 33 ( color , ( oldx , oldy ) , (! x , ! y ))

34 in

35 let line ev =

36 let v = c o m p u t e _ l i n e ev in

37 let _ = E l i o m _ b u s . write % b v in (* w r i t i n g on the bus *) 38 draw ctx v

39 in

40 L w t _ s t r e a m . iter ( draw ctx ) ( E l i o m _ b u s . stream % b ); (* R e a c t i n g to e v e n t s from bus *) 41 run ( m o u s e d o w n s canvas (* For each m o u s e d o w n on the c a n v a s *) 42 ( arr (fun ev -> s e t _ c o o r d ev ; line ev ) (* draw a dot *) 43 >>> first [ m o u s e m o v e s D o m _ h t m l . d o c u m e n t ( arr line );

44 m o u s e u p D o m _ h t m l . d o c u m e n t >>> ( arr line )])) ();

45 }}; (* Then for each m o u s e m o v e draw a line , *) 46 (* and if m o u s e u p draw a line and s t a r t a g a i n c a t c h i n g m o u s e d o w n s *) 47

48 return << < html > < head > < title > Graffiti </ title >

49 < link rel = s t y l e s h e e t href =" ./ css / s t y l e . css "/ > 50 < script src =" ./ o c l o s u r e . js "> </ script > </ head > 51 < body > <h1 > Graffiti </ h1 > </ body > </ html > >>

Figure 2: Full source code of the Graffiti program

Typing is useful to ensure code safety, but it also helps a lot in maintaining and refactoring code. When some parts of the code base is modified, the compiler can show the pro-grammer where he forgot to propagate the changes.

6.

CONCLUSION

The Ocsigen software is now mature and full featured. It has a growing community of users and is released un-der an open source licence (LPGL). Ocsigen provides the most advanced features of Web programming frameworks (like dynamic services or unified client-server programming) but also many unique features: service identification mech-anism, static checking of HTML, persistence of the client program, etc. These unique features come to a large extent from the use of one of the most advanced programming lan-guage (OCaml), known to be very fast, expressive, concise and safe, with many robust libraries.

Many further features have not been presented in this pa-per: an advanced session mechanism, a very concise way to implement event handlers (see lines 41-44), or a flexible in-terface for server push events (see lines 6, 37, 40). Ocsigen also guarantee the absence of code injection on the client, the server, nor in SQL queries, and provides mechanisms to protect angaisnt XSS and data leaks. In our experience, the safety provided by static typing helps a lot in reducing

development time.

Acknowledgements

Many acknowledgements are due to J´erˆome Vouillon, Rapha¨el Proust, Benjamin Canou and Emmanuel Chailloux.

7.

REFERENCES

[1] V. Balat, J. Vouillon, and B. Yakobowski. Experience report: ocsigen, a web programming framework. In ICFP ’09: Proceedings of the 14th ACM SIGPLAN international conference on Functional programming, pages 311–316, Edinburgh, Scotland, 2009. ACM. [2] Dart. http://www.dartlang.org/.

[3] Google closure library.

http://code.google.com/intl/en/closure/library/. [4] Google web toolkit.

http://code.google.com/webtoolkit/. [5] Nodejs. http://nodejs.org/.

[6] C. Queinnec. Continuations and web servers. Higher-Order and Symbolic Computation, 17(4):277–295, Dec. 2004.

[7] M. Serrano, E. Gallesio, and F. Loitsch. Hop, a language for programming the web 2.0. In Dynamic Languages Symposium, Oct. 2006.

Figure

Figure 2 shows the full source code of a client-server draw- draw-ing application (see also a screen-shot in figure1, and a  work-ing version at URL http://ocsigen.org/graffiti)
Figure 2: Full source code of the Graffiti program

Références

Documents relatifs

Ruby packages are called gems and are maintained using the gem utility. Gems can be released with various versions, and a project can be developed that uses a rather specific set

• Compositing: applying styles, interactivity (scripting), animations, synchronizing media elements … to produce static data to be rendered. • Rendering of

In this section you’re going to download, install and prepare your Arduino IDE to work with the ESP8266.. You can program your ESP8266 using the friendly Arduino

An Agent-Oriented Programming Approach based on JaCa By exploiting JaCa, we directly program the Web 2.0 application as a normal JaCa agent program, composed by a workspace with one

In this paper we show this idea in practice by describing a platform for developing Web Client applications using agent programming technologies, in particular Jason for program-

When a column value is omitted from an SQL INSERT statement, then the values for that column in the rows being inserted will be null by default unless you supply your own using the

By default, SELECT returns all the rows from the table, but only shows data for the columns we requested (called the select list).. If you wanted to see all of the columns in a

To illustrate how the use of stored procedures affects the Delphi code you’ll write, we’ll take a simple database task and solve it with SQL embedded within the application and with