Translate

martes, 6 de julio de 2021

Web API en F# y .net 5

Vamos a hacer una web Api con F# y Entity Framework. 

Primero hacer la web Api e instalar Entity Framework. 

dotnet new webapi --language "F#"

dotnet add package Swashbuckle.AspNetCore --version 5.6.3

dotnet new tool-manifest

dotnet tool install dotnet-ef

dotnet tool install paket

dotnet paket convert-from-nuget

dotnet paket add Microsoft.EntityFrameworkCore.Sqlite

dotnet paket add EntityFrameworkCore.FSharp

code  .


Ahora creamos el modelo: 

Hice un archivo Prueba.fs : 

namespace webAPIFsharp

open System

[<CLIMutable>]
type Prueba =
{ Id: int
Name : string
Summary: string }

Y hacemos el dbcontext : 

namespace webAPIFsharp

open System.ComponentModel.DataAnnotations
open Microsoft.EntityFrameworkCore
open EntityFrameworkCore.FSharp.Extensions

type ApiDbContext() =
inherit DbContext()

[<DefaultValue>]
val mutable pruebas : DbSet<Prueba>

member public this.Pruebas with get() = this.pruebas
and set p = this.pruebas <- p

override _.OnModelCreating builder =
builder.RegisterOptionTypes() // enables option values for all entities

override __.OnConfiguring(options: DbContextOptionsBuilder) : unit =
options.UseSqlite("Data Source=base.db") |> ignore

Ahora debemos indicar que compile estas clases agregando estas entradas en el fsproj : 

<Compile Include="Prueba.fs" />
<Compile Include="ApiDbContext.fs" />

Luego compilamos 

dotnet build

Si funciona debemos hacer la migración : 

dotnet ef migrations add Initial

Y ahora agregamos la migración a fsproj :

<Compile Include="Migrations/*.fs" />

Y ahora creamos la base : 

dotnet ef database update

Y ahora agregamos el context a el Startup.fs : 

// Configure EF
services.AddDbContext<ApiDbContext>() |> ignore

Y luego hacemos el controler : 

namespace webAPIFsharp.Controllers

open System
open System.Collections.Generic
open System.Linq
open System.Threading.Tasks
open Microsoft.EntityFrameworkCore
open Microsoft.AspNetCore.Mvc
open Microsoft.Extensions.Logging
open webAPIFsharp

[<ApiController>]
[<Route("[controller]")>]
type PruebaController (logger : ILogger<PruebaController>,
dbContext : ApiDbContext) =
inherit ControllerBase()


[<HttpGet>]
member _.Get() = ActionResult<IEnumerable<Prueba>>(dbContext.Pruebas)

[<HttpPost>]
member _.PostSync(prueba:Prueba) =
dbContext.Pruebas.Add prueba |> ignore
dbContext.SavedChanges |> ignore


[<HttpPost("async")>]
member _.PostAsync(entity: Prueba) =
async {
dbContext.Pruebas.AddAsync(entity) |> ignore
let! _ = dbContext.SaveChangesAsync true |> Async.AwaitTask
return entity
}

[<HttpGet("{id}")>]
member _.getById id =
dbContext.Pruebas
|> Seq.tryFind (fun f -> f.Id = id)

Y listo! 

dotnet run

Yo agregue swagger para mayor detalles dejo link de github: 

https://github.com/emanuelpeg/FsharpWebApiExample