{"id":295,"date":"2018-12-22T17:03:09","date_gmt":"2018-12-22T16:03:09","guid":{"rendered":"https:\/\/corsaire-consulting.fr\/blog\/?p=295"},"modified":"2019-01-15T13:42:59","modified_gmt":"2019-01-15T12:42:59","slug":"functions-as-a-service-premiers-pas","status":"publish","type":"post","link":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/2018\/12\/22\/functions-as-a-service-premiers-pas\/","title":{"rendered":"Functions-as-a-Service, premiers pas"},"content":{"rendered":"<p>La nouvelle vague \u00e0 la mode dont le nom est \u00ab\u00a0Serverless\u00a0\u00bb propose une approche revue et corrig\u00e9e des architectures SOA. Si comme moi le sujet vous int\u00e9resse et que vous souhaitez vous faire une petite id\u00e9e du comment je vous propose ce petit tutoriel. Sans grande ambition il permet de d\u00e9ployer une infrastructure ServerLess dans une machine virtuelle et de voir comment y d\u00e9ployer et ex\u00e9cuter une fonction ou 2.<\/p>\n<p><!--more--><\/p>\n<p>L&rsquo;article ne d\u00e9taille pas les concepts li\u00e9s aux infras ServerLess ni aux Functions-as-a-Service. Le lecteur trouvera facilement sur le web tout un tas d&rsquo;articles traitant de ces sujets. Fn Project publie une bonne introduction sur ces sujets sur son <a href=\"https:\/\/github.com\/fnproject\/docs\/blob\/master\/fn\/general\/introduction.md\">espace Gut Hub<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<p>De quoi avons nous besoin ?<\/p>\n<div class=\"well well-sm\">Une VM sous Linux avec un acc\u00e8s SSH pour s&rsquo;y connecter, ainsi que les droits root pour installer une ou 2 bricoles.<br \/>\nC&rsquo;est tout.<\/div>\n<p>Quelle infra utiliser ?<\/p>\n<div class=\"well well-sm\">Souhaitant disposer d&rsquo;une solution locale aux d\u00e9pends d&rsquo;un cloud provider comme AWS (Lambda) je suis parti du projet open source <a href=\"https:\/\/github.com\/fnproject\/fn\">Fn Project disponible sous Git Hub<\/a>.<\/div>\n<h1>Installation et configuration<\/h1>\n<h2>Installation de Docker<\/h2>\n<p>Et oui, Fn Project s&rsquo;appuie int\u00e9gralement sur Docker pour ses services et pour vos fonctions.<\/p>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bbsudo%20yum%20update%0Asudo%20yum%20update%20nss%20nss-util%20nspr%0Asudo%20yum%20update%20curl%0Asudo%20yum%20install%20yum-utils%20device-mapper-persistent-data%20lvm2%0Asudo%20yum-config-manager%20&#8211;add-repo%20https%3A%2F%2Fdownload.docker.com%2Flinux%2Fcentos%2Fdocker-ce.repo%0Asudo%20yum%20install%20docker-ce%0Asudo%20systemctl%20start%20docker%0Asudo%20systemctl%20enable%20docker%0Asudo%20systemctl%20status%20docker\u00a0\u00bb message=\u00a0\u00bbInstallation et configuration Docker CE\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<p>Ajouter l&rsquo;utilisateur au groupe docker<\/p>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bbsudo%20usermod%20-a%20-G%20docker%20%24USER\u00a0\u00bb message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<h2>Cr\u00e9ation d&rsquo;un repository priv\u00e9 pour Docker<\/h2>\n<p>C&rsquo;est pas une obligation, vous pouvez utiliser un repo distant, faudra vous y connecter (docker login) avant de r\u00e9aliser la suite.<\/p>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bb%23user%20root%0Adocker%20run%20-d%20-p%2050000%3A5000%20&#8211;restart%20always%20&#8211;name%20my-registry%20registry%3Alatest\u00a0\u00bb message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<p>Pour tester la cr\u00e9ation du repository :<\/p>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bbcurl%20http%3A%2F%2Flocalhost%3A50000%2Fv2%2F_catalog\u00a0\u00bb message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<p>En retour, la commande curl doit vous renvoyer la liste des repos (vide) au format json.<\/p>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bb%7B%22repositories%22%3A%5B%5D%7D\u00a0\u00bb message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<h2>Installation de l&rsquo;infrastructure Fn<\/h2>\n<p>Tout est pr\u00e9vu par le projet <em>Fn Project<\/em>. Un script d&rsquo;installation pour Linux est disponible sous Git Hub.<\/p>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bbsudo%20curl%20-LSs%20https%3A%2F%2Fraw.githubusercontent.com%2Ffnproject%2Fcli%2Fmaster%2Finstall%20%7C%20sh\u00a0\u00bb message=\u00a0\u00bbInstallation de l&rsquo;infra fn\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<p>D\u00e9marrage du serveur<\/p>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bbfn%20start\u00a0\u00bb message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<p>Simple et efficace.<\/p>\n<p>Ensuite tout se fait via la commande \u00ab\u00a0fn\u00a0\u00bb<\/p>\n<h1>Cr\u00e9ation de l&rsquo;application<\/h1>\n<p>L&rsquo;application illustrant cet article est une petite calculatrice qui permet de r\u00e9aliser des op\u00e9rations toutes simples sur des entiers. C&rsquo;est pas l&rsquo;application de l&rsquo;ann\u00e9e, je le conc\u00e8de mais l\u00e0 n&rsquo;est pas le propos.<\/p>\n<p>Les fonctions sont \u00e9crites en Go histoire de pimenter un peu le sujet. Fn Project supporte Go, Java, Python, Node.js et Ruby.<\/p>\n<p>Cr\u00e9ation d&rsquo;un r\u00e9pertoire pour stocker le code source de l&rsquo;application et des fonctions.<\/p>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bbmkdir%20calculatrice%0Acd%20calculatrice%0Aecho%20&rsquo;name%3A%20calculatrice&rsquo;%20%3E%20app.yaml\u00a0\u00bb message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<h1>Cr\u00e9ation des fonctions<\/h1>\n<p>Cr\u00e9ation de 3 fonctions :<\/p>\n<ul>\n<li>une fonction racine de l&rsquo;application (sans nom)<\/li>\n<li>Une fonction addition<\/li>\n<li>Une fonction soustraction<\/li>\n<\/ul>\n<p>Par d\u00e9faut chaque fonction accepte un param\u00e8tre \u00ab\u00a0Name\u00a0\u00bb et revoie un message texte \u00ab\u00a0Hello &lt;Name&gt;\u00a0\u00bb ou \u00ab\u00a0Hello World\u00a0\u00bb si le param\u00e8tre n&rsquo;est pas indiqu\u00e9.<\/p>\n<p>Les \u00e9changes avec la fonction se font par d\u00e9faut au format JSON, ce n&rsquo;est pas une obligation.<\/p>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bbfn%20init%20&#8211;runtime%20go%20&#8211;trigger%20http%0Afn%20init%20&#8211;runtime%20go%20&#8211;trigger%20http%20soustraction%0Afn%20init%20&#8211;runtime%20go%20&#8211;trigger%20http%20addition\u00a0\u00bb message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<p>Chaque fonction est d\u00e9clench\u00e9e (trigger) par un appel HTTP sur son URL. Pour le moment, Fn Project ne supporte pas d&rsquo;autre mode de d\u00e9clenchement.<\/p>\n<p>&nbsp;<\/p>\n<p>Chaque fonction sera cr\u00e9\u00e9e dans&nbsp; un sous-r\u00e9pertoire&nbsp; de l&rsquo;application comportant par d\u00e9faut 3 fichiers :<\/p>\n<ul>\n<li>func.go : le code source Go de la fonction<\/li>\n<li>func.yaml : les m\u00e9ta-donn\u00e9es associ\u00e9es \u00e0 la fonction<\/li>\n<li>Gopkg.toml : D\u00e9pendances Go<\/li>\n<\/ul>\n<h2>Codes sources GO<\/h2>\n<h3>Fonction addition<\/h3>\n<p>[pastacode lang=\u00a0\u00bbjava\u00a0\u00bb manual=\u00a0\u00bbpackage%20main%0A%0Aimport%20(%0A%20%20%20%20%20%20%20%20%22context%22%0A%20%20%20%20%20%20%20%20%22encoding%2Fjson%22%0A%20%20%20%20%20%20%20%20%2F%2F%22fmt%22%0A%20%20%20%20%20%20%20%20%22io%22%0A%0A%20%20%20%20%20%20%20%20fdk%20%22github.com%2Ffnproject%2Ffdk-go%22%0A)%0A%0Afunc%20main()%20%7B%0A%20%20%20%20%20%20%20%20fdk.Handle(fdk.HandlerFunc(myHandler))%0A%7D%0A%0Atype%20Params%20struct%20%7B%0A%20%20%20%20%20%20%20%20Operande%20string%0A%20%20%20%20%20%20%20%20Value%20int%0A%7D%0A%0A%0Afunc%20add(a%20int%2C%20b%20int)%20int%20%7B%0A%20%20%20%20%20%20%20%20return%20a%2Bb%0A%7D%0A%0Afunc%20myHandler(ctx%20context.Context%2C%20in%20io.Reader%2C%20out%20io.Writer)%20%7B%0A%20%20%20%20%20%20%20%20var%20p%20Params%0A%20%20%20%20%20%20%20%20dec%20%3A%3D%20json.NewDecoder(in)%0A%20%20%20%20%20%20%20%20var%20result%20int%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20err%20%3A%3D%20dec.Decode(%26p)%3B%20err%20%3D%3D%20io.EOF%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20err%20!%3D%20nil%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result%20%3D%20add(result%2C%20p.Value)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20msg%20%3A%3D%20struct%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Resultat%20int%20%60json%3Aresult%60%0A%20%20%20%20%20%20%20%20%7D%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Resultat%3A%20result%2C%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20json.NewEncoder(out).Encode(%26msg)%0A%7D\u00a0\u00bb message=\u00a0\u00bbCode source de la fonction addition en Go\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<h3>Fonction soustraction<\/h3>\n<p>[pastacode lang=\u00a0\u00bbjava\u00a0\u00bb manual=\u00a0\u00bbpackage%20main%0A%0Aimport%20(%0A%20%20%20%20%20%20%20%20%22context%22%0A%20%20%20%20%20%20%20%20%22encoding%2Fjson%22%0A%20%20%20%20%20%20%20%20%2F%2F%22fmt%22%0A%20%20%20%20%20%20%20%20%22io%22%0A%0A%20%20%20%20%20%20%20%20fdk%20%22github.com%2Ffnproject%2Ffdk-go%22%0A)%0A%0Afunc%20main()%20%7B%0A%20%20%20%20%20%20%20%20fdk.Handle(fdk.HandlerFunc(myHandler))%0A%7D%0A%0Atype%20Params%20struct%20%7B%0A%20%20%20%20%20%20%20%20Operande%20string%0A%20%20%20%20%20%20%20%20Value%20int%0A%7D%0A%0A%0Afunc%20substract(a%20int%2C%20b%20int)%20int%20%7B%0A%20%20%20%20%20%20%20%20return%20a-b%0A%7D%0A%0Afunc%20myHandler(ctx%20context.Context%2C%20in%20io.Reader%2C%20out%20io.Writer)%20%7B%0A%20%20%20%20%20%20%20%20var%20p%20Params%0A%20%20%20%20%20%20%20%20dec%20%3A%3D%20json.NewDecoder(in)%0A%20%20%20%20%20%20%20%20var%20result%20int%0A%20%20%20%20%20%20%20%20var%20firstOp%20%3D%20true%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20err%20%3A%3D%20dec.Decode(%26p)%3B%20err%20%3D%3D%20io.EOF%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20err%20!%3D%20nil%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(firstOp)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20firstOp%20%3D%20false%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result%20%3D%20p.Value%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result%20%3D%20substract(result%2C%20p.Value)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20msg%20%3A%3D%20struct%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Resultat%20int%20%60json%3Aresult%60%0A%20%20%20%20%20%20%20%20%7D%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Resultat%3A%20result%2C%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20json.NewEncoder(out).Encode(%26msg)%0A%7D%0A\u00a0\u00bb message=\u00a0\u00bbCode source de la fonction soustraction en Go\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<h2>D\u00e9ploiement des fonctions<\/h2>\n<p>D\u00e9ploiement de toutes les fonctions de l&rsquo;application \u00ab\u00a0calculatrice\u00a0\u00bb dans le repo Docker local :<\/p>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bbfn%20deploy%20&#8211;all%20&#8211;local\u00a0\u00bb message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<p>&nbsp;<\/p>\n<h2>Quelques commandes utiles<\/h2>\n<p>Obtenir de l&rsquo;aide<\/p>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bbfn%20&#8211;help%0Afn%20list%20&#8211;help%0A&#8230;\u00a0\u00bb message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<p>Liste des applications<\/p>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bb%24%20fn%20list%20apps%0ANAME%20%20%20%20%20%20%20%20%20%20%20%20ID%0Acalculatrice%20%20%20%2001CZ7ZZVKHNG8G00RZJ0000001&Prime; message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<p>Liste des fonction d&rsquo;une application<\/p>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bb%24%20fn%20list%20fn%20calculatrice%0ANAME%20%20%20%20%20%20%20%20%20%20%20%20IMAGE%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ID%0Aaddition%20%20%20%20%20%20%20%20addition%3A0.0.2%20%20%20%20%20%20%20%20%20%2001CZ800XGENG8G00RZJ0000002%0Acalculatrice%20%20%20%20calculatrice%3A0.0.2%20%20%20%20%20%2001CZ801NR0NG8G00RZJ0000006%0Asoustraction%20%20%20%20soustraction%3A0.0.2%20%20%20%20%20%2001CZ802DWFNG8G00RZJ000000A\u00a0\u00bb message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<p>Liste des triggers d&rsquo;une application<\/p>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bb%24%20fn%20list%20tr%20calculatrice%0AFUNCTION%20%20%20%20%20%20%20%20NAME%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ID%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20TYPE%20%20%20%20SOURCE%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ENDPOINT%0Aaddition%20%20%20%20%20%20%20%20addition-trigger%20%20%20%20%20%20%20%2001CZ80GKYMNG8G00RZJ0000003%20%20%20%20%20%20http%20%20%20%20%2Faddition-trigger%20%20%20%20%20%20%20http%3A%2F%2Flocalhost%3A8080%2Ft%2Fcalculatrice%2Faddition-trigger%0Acalculatrice%20%20%20%20calculatrice-trigger%20%20%20%2001CZ80HCSYNG8G00RZJ0000007%20%20%20%20%20%20http%20%20%20%20%2Fcalculatrice-trigger%20%20%20http%3A%2F%2Flocalhost%3A8080%2Ft%2Fcalculatrice%2Fcalculatrice-trigger%0Asoustraction%20%20%20%20soustraction-trigger%20%20%20%2001CZ82MVHFNG8G00RZJ000000N%20%20%20%20%20%20http%20%20%20%20%2Fsoustraction-trigger%20%20%20http%3A%2F%2Flocalhost%3A8080%2Ft%2Fcalculatrice%2Fsoustraction-trigger%0A\u00a0\u00bb message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<p>Liste des appels effectu\u00e9s vers une fonction<\/p>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bbfn%20list%20calls%20calculatrice%20addition\u00a0\u00bb message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<h1>Tests<\/h1>\n<p>Il est possible de tester une fonction avec la commande fn invoke.<\/p>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bb%24%20fn%20invoke%20calculatrice%20calculatrice%0Atime%3D%222018-12-22T15%3A34%3A02Z%22%20level%3Dinfo%20msg%3D%22starting%20call%22%20action%3D%22server.handleFnInvokeCall)-fm%22%20app_id%3D01CZ80FF3RNG8G00RZJ0000001%20container_id%3D01CZ8PDTHVNG8G00RZJ000000S%20fn_id%3D01CZ80HCSRNG8G00RZJ0000006%20id%3D01CZ8PDTHVNG8G00RZJ000000R%0A%7B%22message%22%3A%22Hello%20World%22%7D%0A\u00a0\u00bb message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<p>Exemple d&rsquo;invocation avec param\u00e8tres :<\/p>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bb%24%20echo%20-n%20&rsquo;%7B%22Name%22%3A%22Bob%22%7D&rsquo;%20%7C%20fn%20invoke%20calculatrice%20calculatrice%0Atime%3D%222018-12-22T15%3A46%3A52Z%22%20level%3Dinfo%20msg%3D%22starting%20call%22%20action%3D%22server.handleFnInvokeCall)-fm%22%20app_id%3D01CZ80FF3RNG8G00RZJ0000001%20container_id%3D01CZ8Q4Z9VNG8G00RZJ0000013%20fn_id%3D01CZ80HCSRNG8G00RZJ0000006%20id%3D01CZ8Q5B3NNG8G00RZJ0000015%0A%7B%22message%22%3A%22Hello%20Bob%22%7D%0A\u00a0\u00bb message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<p>&nbsp;<\/p>\n<p>Sinon, utiliser curl par exemple pour&nbsp; tester chaque fonction.<\/p>\n<h2>Addition<\/h2>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bb%24%20curl%20-d%20&rsquo;%7B%22Operande%22%3A%22a%22%2C%20%22Value%22%3A40%7D%7B%22Operande%22%3A%22b%22%2C%20%22Value%22%3A10%7D%7B%22Operande%22%3A%22c%22%2C%20%22Value%22%3A50%7D&rsquo;%20http%3A%2F%2Flocalhost%3A8080%2Ft%2Fcalculatrice%2Faddition-trigger\u00a0\u00bb message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<p>R\u00e9sultat :<\/p>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bbtime%3D%222018-12-22T13%3A28%3A06Z%22%20level%3Dinfo%20msg%3D%22starting%20call%22%20action%3D%22server.handleHTTPTriggerCall)-fm%22%20app_id%3D01CZ80FF3RNG8G00RZJ0000001%20app_name%3Dcalculatrice%20container_id%3D01CZ8F6EGGNG8G00RZJ000000B%20fn_id%3D01CZ80GKYDNG8G00RZJ0000002%20id%3D01CZ8F783ENG8G00RZJ000000E%20trigger_source%3D%2Faddition-trigger%0A%7B%22Resultat%22%3A100%7D\u00a0\u00bb message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<h2>Soustraction<\/h2>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bbcurl%20-d%20&rsquo;%7B%22Operande%22%3A%22a%22%2C%20%22Value%22%3A40%7D%7B%22Operande%22%3A%22b%22%2C%20%22Value%22%3A10%7D&rsquo;%20http%3A%2F%2Flocalhost%3A8080%2Ft%2Fcalculatrice%2Fsoustraction-trigger\u00a0\u00bb message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<p>R\u00e9sultat :<\/p>\n<p>[pastacode lang=\u00a0\u00bbbash\u00a0\u00bb manual=\u00a0\u00bbtime%3D%222018-12-22T15%3A19%3A28Z%22%20level%3Dinfo%20msg%3D%22starting%20call%22%20action%3D%22server.handleHTTPTriggerCall)-fm%22%20app_id%3D01CZ80FF3RNG8G00RZJ0000001%20app_name%3Dcalculatrice%20container_id%3D01CZ8NK53HNG8G00RZJ000000P%20fn_id%3D01CZ82MVHANG8G00RZJ000000M%20id%3D01CZ8NK53HNG8G00RZJ000000N%20trigger_source%3D%2Fsoustraction-trigger%0A%7B%22Resultat%22%3A30%7D%0A\u00a0\u00bb message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<p>Enjoy !<\/p>\n","protected":false},"excerpt":{"rendered":"<p>La nouvelle vague \u00e0 la mode dont le nom est \u00ab\u00a0Serverless\u00a0\u00bb propose une approche revue et corrig\u00e9e des architectures SOA. Si comme moi le sujet vous int\u00e9resse et que vous souhaitez vous faire une petite id\u00e9e du comment je vous propose ce petit tutoriel. Sans grande ambition il permet de d\u00e9ployer une infrastructure ServerLess dans [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[55],"tags":[51,54,52,53],"class_list":["post-295","post","type-post","status-publish","format-standard","hentry","category-serverless","tag-faas","tag-fn-project","tag-functions-as-a-service","tag-go"],"_links":{"self":[{"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/posts\/295","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=295"}],"version-history":[{"count":24,"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/posts\/295\/revisions"}],"predecessor-version":[{"id":356,"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/posts\/295\/revisions\/356"}],"wp:attachment":[{"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=295"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=295"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=295"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}