Skip to content

Instantly share code, notes, and snippets.

@akhansari
Last active September 9, 2023 13:33
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save akhansari/e91a146b76eb529b25879dbf8b3eaa5f to your computer and use it in GitHub Desktop.
Save akhansari/e91a146b76eb529b25879dbf8b3eaa5f to your computer and use it in GitHub Desktop.
F# : Different ways to create an API without a dependency
open System
open Microsoft.AspNetCore.Builder
open Microsoft.AspNetCore.Http
open Microsoft.AspNetCore.Routing
type Item = { Id: int32; Name: string; Price: decimal }
let rnd = Random()
let getProducts () =
[ for _ in 1..3 do { Id = rnd.Next 100; Name = "Blueberry"; Price = 10m } ]
let getProduct id =
{ Id = id; Name = "Blueberry"; Price = 20m }
let addProduct (model: {| Name: string; Price: decimal |}) =
let product = { Id = rnd.Next 100; Name = model.Name; Price = model.Price }
Results.Created($"/products/{product.Id}", product)
let getArticle (context: HttpContext) =
let id = context.GetRouteValue "id" |> Convert.ToInt32
{ Id = id; Name = "Blueberry"; Price = 20m }
|> context.Response.WriteAsJsonAsync
let app = WebApplication.CreateBuilder().Build()
// delegates have to be lambda expressions cast to Func<>
app.MapGet("/products", Func<_> getProducts) |> ignore
app.MapGet("/products/{id}", Func<_,_> (fun id -> getProduct id)) |> ignore
app.MapPost("/products", Func<_,_> (fun model -> addProduct model)) |> ignore
// request delegates are more flexible
app.MapGet("/articles/{id}", RequestDelegate getArticle) |> ignore
app.Run()
namespace MyApi
open System
open Microsoft.AspNetCore.Builder
open Microsoft.AspNetCore.Mvc
open Microsoft.Extensions.DependencyInjection
open Microsoft.Extensions.Hosting
type Item = { Id: int32; Name: string; Price: decimal }
type ItemAddModel = { Name: string; Price: decimal }
[<ApiController>]
[<Route "[controller]">]
type ProductsController () =
inherit ControllerBase ()
let rnd = Random()
[<HttpGet>]
member _.GetProducts () =
[ for _ in 1..3 do { Id = rnd.Next 100; Name = "Blueberry"; Price = 10m } ]
[<HttpGet "{id}">]
member _.GetProduct id =
{ Id = id; Name = "Blueberry"; Price = 20m }
[<HttpPost>]
[<ProducesResponseType 201>]
member this.AddProduct model =
let product = { Id = rnd.Next 100; Name = model.Name; Price = model.Price }
this.CreatedAtAction(nameof this.GetProduct, {| id = product.Id |}, product)
module Program =
[<EntryPoint>]
let main args =
let builder = WebApplication.CreateBuilder args
//builder.Services.AddSwaggerGen() |> ignore
builder.Services.AddControllers() |> ignore
let app = builder.Build()
//app.UseSwagger().UseSwaggerUI() |> ignore
app.MapControllers() |> ignore
app.Run()
0
###
GET http://localhost:5000/products
###
GET http://localhost:5000/products/123
###
POST http://localhost:5000/products
content-type: application/json
{
"name": "Cat Food",
"price": 30
}
###
GET http://localhost:5000/articles/456
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment