Update: Quelques modifications sont à prendre en compte suite à l’arrivée de la version 1 de Go (vous pouvez utiliser l’application gofix pour mettre à jour votre code et changer la version d’api de 3 à go1).
Le but de cet article est d’expliquer comment mettre en ligne une application AppEngine en Go.
Je ne vais pas m’étendre sur l’installation du SDK et sur la structure du langage :
- Installez le SDK
- Suivez le tuto en ligne qui est très bien fait
Et en avant pour cette première application.
Développement d’un générateur de triangle de Sierpinski en Go
Ce programme tout bête utilise un algorithme binaire tout simple pour générer un triangle de Sierpinski dont la taille est paramétrable (paramètre passé en ligne de commande). Pour plus de détails, suivez les commentaires du programme.
package main import ( "fmt" "strings" "strconv" "flag" "os" ) func main() { // Analyse de la ligne de commande flag.Parse() // La variable chargée de stocker le nombre de lignes // à afficher var nbLignes int // Parsing des paramètres en ligne de commande if flag.NArg() == 0 { // Si pas d'arguments => 16 lignes nbLignes = 16 } else { // Sinon, on prend la valeur passée en paramètres var err os.Error nbLignes, err = strconv.Atoi(flag.Arg(0)) if err != nil { fmt.Println(err) os.Exit(1) } } // Algorithme d'affichage du triangle for i:=0; i<=(nbLignes - 1); i++ { // Padding pour redresser le triangle fmt.Print(strings.Repeat(" ", nbLignes -i)) // Construction d'une ligne for j:=0;j<=i;j++ { if ((^i & j) != 0) { fmt.Print(" ") } else { fmt.Print(" *") } } fmt.Print("\n") } }
Exemple de triangle généré :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Modification du code pour tourner sur GAE
Nous allons maintenant nous attaquer à la version Google AppEngine.
Tout d’abord, installez le SDK (passez par le site en anglais pour pouvoir télécharger le sdk : http://code.google.com/intl/en/appengine/downloads.html)
Un programme Google AppEngine se base sur le package http de Go pour mettre en place un handler de connexion.
Exemple:
import "http" func init() { http.HandleFunc("/", handler) } func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello"); }
En première intention, nous allons faire un programme qui affiche un triangle de Sierpinski de 16 lignes, non paramétrable.
Il faudra alors :
- Modifier le nom de package (le package main est réservé aux programmes individuels)
- Ajouter une procédure init()
- Modifier la méthode main en handler HTTP
- Supprimer le code de paramétrage du nombre de lignes
- Supprimer les imports inutilisés
Voici ce que ça donne :
package handler import ( "fmt" "strings" "net/http" ) func init() { http.HandleFunc("/", handler) } func handler(w http.ResponseWriter, r *http.Request) { nbLignes := 16 fmt.Fprint(w, "<html><pre>"); // Algorithme d'affichage du triangle for i:=0; i<=(nbLignes - 1); i++ { // Padding pour redresser le triangle fmt.Fprint(w, strings.Repeat(" ", nbLignes -i)) // Construction d'une ligne for j:=0;j<=i;j++ { if ((^i & j) != 0) { fmt.Fprint(w," ") } else { fmt.Fprint(w," *") } } fmt.Fprint(w,"\n") } fmt.Fprint(w, "</pre></html>"); }
Publication de l’application sur Google AppEngine
Pour publier sur GAE, votre application doit respecter une arborescence du type :
sierpinski/ app.yaml sierpinski/ sierpinski.go
où app.yaml est le descripteur de l’application :
application: sierpinski-go version: 1 runtime: go api_version: go1 handlers: - url: /.* script: _go_app
Les éléments à indiquer dans le fichier sont les suivants :
- L’identifiant de l’application (que vous déclarez lors de l’enregistrement de l’application dans GAE)
- La version de l’application (1 pour l’instant)
- La version d’API de go à utiliser
- Dans la partie handlers, il faut déclarer l’expression régulière servant à déclarer les pages devant être servies par le script; ici, toutes les pages
Si tout est ok, vous pouvez maintenant tester votre application :
dev_appserver.py sierpinski/
Connectez votre navigateur sur http://localhost:8080 et vous devriez obtenir votre triangle
Dernière étape : la publication.
- Connectez vous à GAE : https://appengine.google.com/
- Enregistrez un nom d’application disponible (et reportez le dans app.yaml)
Lancez alors la commande :
appcfg.py update sierpinski/
Après quelques secondes, votre application sera disponible sur GAE.
Le résultat :
[ http://sierpinski-go.appspot.com ]
Bonus : paramétrer le nombre de lignes à afficher
Pour se faire plaisir et pousser un peu plus le concept, ajoutons un paramètrage du nombre de lignes à afficher :
package handler import ( "fmt" "strings" "strconv" "net/http" ) func init() { http.HandleFunc("/", handler) } func handler(w http.ResponseWriter, r *http.Request) { // Nombre de lignes par défaut nbLignes := 16 // Parsing du nombre de ligne depuis l'url nbLignesParam := r.FormValue("nbLignes") if nbLignesParam != "" { nbConv, err := strconv.Atoi(nbLignesParam) if err == nil && nbConv <= 64 { nbLignes = nbConv } } fmt.Fprint(w, "<html><pre>"); for i:=0; i<=(nbLignes - 1); i++ { // Padding pour redresser le triangle fmt.Fprint(w, strings.Repeat(" ", nbLignes -i)) // Construction d'une ligne for j:=0;j<=i;j++ { if ((^i & j) != 0) { fmt.Fprint(w," ") } else { fmt.Fprint(w," *") } } fmt.Fprint(w,"\n") } fmt.Fprint(w, "</pre></html>"); }
(peu de modifications : ajout de l’import strconv et parsing de l’url avec request.FormValue)
On redéploie !
appcfg.py update sierpinski/
Si vous avez déjà déployé la version précédente, il faudra sélectionner la bonne version à publier dans la console appengine
Et voilà le résultat :
[ http://sierpinski-go.appspot.com/?nbLignes=64 ]
ou encore, la version 32 lignes :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *