Bonjour à tous dans un nouvel article sur la plateforme Dev.to
. Dans cette occasionne, nous apprendrons brièvement comment faire une Azure Fonction en utilisant F# pour la développer.
Dans la première version d'Azure Fonctions, nous pouvions faire facilement une fonction en utilisant un script fsx, tandis que dans la dernière version d'Azure Fonctions nous devons précompiler et uploader nos scripts fs
Après de voir la documentation, j'ai découvert qu'il n'y a pas un bon exemple pour faire une fonction azure avec F#, donc la Template ne fonctionne pas alors j'ai déçu de faire ce petit tutoriel.
Requis
On a besoin d'installer le suivant logiciel:
- Visual Studio Code ou votre éditeur du texte préféré.
- Installez F# et NodeJS avec le package Azure Functions Core Tools
- Installez le .NET Core CLI
- Optionnellement vous pourriez créer un compte Microsoft Azure en cas de vouloir publier votre fonction.
Temp de code 1..2..3
Pas 1
D'abord on va vérifier notre installation alors on va ouvrir un terminal unix et écrire les commandes :
darkhero> func --version # 3.0.3388
darkhero> func templates list # on verra qu'il n'y a pas F# templates
darkhero> dotnet --version # 5.0.201
Malgré la faute d'une Template F#, on peut créer une fonctionne en exécutant le commande :
# Ce commande va créer notre fonctionne base dont F# sera la langue pour programmer
darkhero> dotnet new classlib --language F# --name HelloDevTo
darkhero> cd HelloDevTo && ls
HelloDevTo.fsproj Library.fs obj
On a 2 fichiers, HelloDevTo.fsproj
et Library.fs
, le premier contient l'information essentiel de notre projet F#, toutes les libraires vont ici. Library.fs
est le fichier F# crée par default, alors on va l'effacer et créer le fichier HelloFunctions.fs
Pas 2
Pour ajouter la fonctionnalité d'une Azure Fonction dans notre code, il est nécessaire d'ajouter le package Microsoft.Net.Sdk.Functions, après on doit créer les fichiers host.json, local.settings.json & function.json.
Pour ajouter le package, on va exécuter la suivante ligne de code:
darkhero> dotnet add package Microsoft.NET.Sdk.Functions
Pour le fichier host.json, on va copier (ou écrire) le suivante code:
{
"version": "2.0",
}
Pour le fichier local.settings.json:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet"
}
}
Finalement dans le fichier function.json:
{
"bindings": [
{
"type": "httpTrigger",
"methods": [
"get",
"post"
],
"authLevel": "anonymous",
"name": "req"
}
],
"disabled": false
}
Après de tenir les fichiers nécessaires, on va modifier le fichier HelloDevTo.fsproj, car on doit ajouter les fichiers qu'on avait créés avant. Si on ouvre ce fichier, on verrait le suivant :
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="Library.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.7" />
</ItemGroup>
</Project>
Cependant, il n'y aura la configuration précise d'un azure fonction, pourtant, on va faire des petites modifications afin de lui donner la fonctionnalité. Pour faire cela, il n'est que nécessaire de changer et ajouter quelques lignes de code :
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AzureFunctionsVersion>v2</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<Compile Include="HelloFunc.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.7" />
</ItemGroup>
<ItemGroup>
<Content Include="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</Content>
</ItemGroup>
</Project>
Après d'avoir changé le contenu de fichier fsproj, on va créer le fichier HelloFunc.fs, puis on va passer l'exemple avec C# à F#. Ici le code C#:
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace FunctionApp1
{
public static class Function1
{
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
return name != null
? (ActionResult)new OkObjectResult($"Hello, {name}")
: new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}
}
}
Maintenant, on va convertir ça. Ici le code transformé:
namespace HelloDevTo
open System
open Microsoft.AspNetCore.Mvc
open Microsoft.Azure.WebJobs
open Microsoft.Azure.WebJobs.Extensions.Http
open Microsoft.AspNetCore.Http
open Microsoft.Extensions.Logging
open Newtonsoft.Json
open System.IO
module HelloFunction =
// Define a nullable container to deserialize into.
[<AllowNullLiteral>]
type NameContainer() =
member val Name = "" with get, set
// For convenience, it's better to have a central place for the literal.
[<Literal>]
let Name = "name"
// Nombre de la funcion
[<FunctionName("HelloFunction")>]
// Nivel de Autorizacion para consumir la funcion, la cambiamos a Anonymous ya que para este ejemplo no requerimos nada de seguridad
// Tambien que metodos HTTP acepta
// Route nos permite customizar el nombre de salida al publicar la funcion
let Run([<HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)>] req : HttpRequest, log: ILogger) =
async {
log.LogInformation("F# HTTP trigger function processed a request.")
let nameOpt =
if req.Query.ContainsKey(Name) then
Some(req.Query.[Name].[0])
else
None
use stream = new StreamReader(req.Body)
let! reqBody = stream.ReadToEndAsync() |> Async.AwaitTask
let data = JsonConvert.DeserializeObject<NameContainer>(reqBody)
let name =
match nameOpt with
| Some n -> n
| None ->
match data with
| null -> ""
| nc -> nc.Name
let responseMessage =
if (String.IsNullOrWhiteSpace(name)) then
"Please pass a name on the query string or in the request body"
else
$"Hello, {name}"
return OkObjectResult(responseMessage) :> IActionResult
} |> Async.StartAsTask
Ensuite en utilisant la terminal, on exécute func start --verbose
, ça va lancer la fonctionne dans notre environnement local et nous recevrons un lien avec lequel on peut tester, dans mon cas, j'utilisais curl pour y tester.
darkhero> curl http://localhost:7071/api/HelloFunction
Please pass a name on the query string or in the request body
darkhero> curl http://localhost:7071/api/HelloFunction?name=DevTo
Hello, DevTo
Voilà, on a un Azure Fonction qui utilise F# comme langue de programmation. Aussi il est possible de travailler avec Azure Fonction d'une autre manière plus simple, cependant, dans cet article, on verra seulement ce premier essai.
En fin, j’ai fait toutes ses pas pour créer un azure fonction avec F#, tandis que la création d’une avec une autre langue de programmation va être facile puisque celle-ci est plus populaire, par exemple, quand on a installé func
et on voit la liste des langues supportés, on peut voir que seulement a templates pour C#, NodeJS, PowerShell et Python, même si on a besoin de travailler avec Golang, F#, Rust ou Deno, nous devons créer nos projets d’une autre façon, étant donné que Microsoft oublie parfois qu’il peut supporter des autres langues de programmation. Pour moi, ça a été amusant puisque j’ai appris beaucoup pendants les recherches.
Top comments (0)