Update F# API with a stolen template
This commit is contained in:
parent
60a278362a
commit
f13495cf89
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"FSharp.suggestGitignore": false
|
||||
}
|
||||
39
api/Blog.fs
Normal file
39
api/Blog.fs
Normal file
@ -0,0 +1,39 @@
|
||||
module Blog
|
||||
|
||||
open System
|
||||
open System.Threading.Tasks
|
||||
open Microsoft.AspNetCore.Http
|
||||
open Giraffe
|
||||
|
||||
[<CLIMutable>]
|
||||
type BlogPost = {
|
||||
title: string
|
||||
content: string
|
||||
}
|
||||
|
||||
type BlogDb() =
|
||||
|
||||
let mutable allBlogPosts : BlogPost list = []
|
||||
|
||||
member this.GetAllPosts = fun() -> allBlogPosts
|
||||
|
||||
member this.AddPost (newPost : BlogPost) =
|
||||
allBlogPosts <- (newPost::allBlogPosts)
|
||||
allBlogPosts
|
||||
|
||||
type BlogServiceTree = {
|
||||
getBlogDb : unit -> BlogDb
|
||||
}
|
||||
|
||||
let getPostsHttpHandler (serviceTree: BlogServiceTree) =
|
||||
fun (next : HttpFunc) (ctx : HttpContext) ->
|
||||
json (serviceTree.getBlogDb().GetAllPosts()) next ctx
|
||||
|
||||
let createPostHttpHandler (serviceTree: BlogServiceTree) =
|
||||
fun (next : HttpFunc) (ctx : HttpContext) ->
|
||||
task {
|
||||
let! newPostJson = ctx.BindJsonAsync<BlogPost>()
|
||||
serviceTree.getBlogDb().AddPost(newPostJson) |> ignore
|
||||
return! json (newPostJson) next ctx
|
||||
}
|
||||
|
||||
13
api/Controllers/PageController.fs
Normal file
13
api/Controllers/PageController.fs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace api.Controllers
|
||||
|
||||
open System
|
||||
open Microsoft.AspNetCore.Mvc
|
||||
|
||||
[<Route("api/[controller]")>]
|
||||
[<ApiController>]
|
||||
type PageController() =
|
||||
inherit ControllerBase()
|
||||
|
||||
[<HttpGet>]
|
||||
member this.Get() =
|
||||
Ok("Hello, World!")
|
||||
@ -1,38 +0,0 @@
|
||||
namespace api.Controllers
|
||||
|
||||
open System
|
||||
open System.Collections.Generic
|
||||
open System.Linq
|
||||
open System.Threading.Tasks
|
||||
open Microsoft.AspNetCore.Mvc
|
||||
open Microsoft.Extensions.Logging
|
||||
open api
|
||||
|
||||
[<ApiController>]
|
||||
[<Route("[controller]")>]
|
||||
type WeatherForecastController (logger : ILogger<WeatherForecastController>) =
|
||||
inherit ControllerBase()
|
||||
|
||||
let summaries =
|
||||
[|
|
||||
"Freezing"
|
||||
"Bracing"
|
||||
"Chilly"
|
||||
"Cool"
|
||||
"Mild"
|
||||
"Warm"
|
||||
"Balmy"
|
||||
"Hot"
|
||||
"Sweltering"
|
||||
"Scorching"
|
||||
|]
|
||||
|
||||
[<HttpGet>]
|
||||
member _.Get() =
|
||||
let rng = System.Random()
|
||||
[|
|
||||
for index in 0..4 ->
|
||||
{ Date = DateTime.Now.AddDays(float index)
|
||||
TemperatureC = rng.Next(-20,55)
|
||||
Summary = summaries.[rng.Next(summaries.Length)] }
|
||||
|]
|
||||
39
api/Database.fs
Normal file
39
api/Database.fs
Normal file
@ -0,0 +1,39 @@
|
||||
module Database
|
||||
|
||||
open System.Data.SqlClient
|
||||
open Microsoft.Extensions.Configuration
|
||||
open System.IO
|
||||
|
||||
let configuration =
|
||||
let builder = new ConfigurationBuilder()
|
||||
let path = Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json")
|
||||
builder.AddJsonFile(path, optional = false, reloadOnChange = true) |> ignore
|
||||
builder.Build()
|
||||
|
||||
let connectionString = configuration.GetConnectionString("DefaultConnection")
|
||||
|
||||
type Page =
|
||||
{ Id : int
|
||||
Title : string
|
||||
Subtitle : string }
|
||||
|
||||
let getPages () =
|
||||
use connection = new SqlConnection(connectionString)
|
||||
connection.Open()
|
||||
|
||||
use command = new SqlCommand("SELECT * FROM basic_pages", connection)
|
||||
|
||||
use reader = command.ExecuteReader()
|
||||
|
||||
let rec readData (acc: List<Page>) =
|
||||
if reader.Read() then
|
||||
let page = {
|
||||
Id = reader.GetInt32(0)
|
||||
Title = reader.GetString(1)
|
||||
Subtitle = reader.GetString(2)
|
||||
}
|
||||
readData (page :: acc)
|
||||
else
|
||||
acc
|
||||
|
||||
readData []
|
||||
29
api/Dockerfile
Normal file
29
api/Dockerfile
Normal file
@ -0,0 +1,29 @@
|
||||
# Base image
|
||||
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
|
||||
|
||||
# Add tools
|
||||
RUN apt-get update && \
|
||||
apt-get install -y curl
|
||||
|
||||
# Set the working directory inside the container
|
||||
WORKDIR /app
|
||||
|
||||
# Copy the project file and restore dependencies
|
||||
COPY *.fsproj .
|
||||
RUN dotnet restore
|
||||
|
||||
# Copy the source code and build the application
|
||||
COPY . .
|
||||
RUN dotnet publish -c Release -o out
|
||||
|
||||
# Build the runtime image
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:6.0
|
||||
WORKDIR /app
|
||||
COPY --from=build-env /app/out .
|
||||
|
||||
# Set the entry point command
|
||||
CMD ["dotnet", "api.dll"]
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=5s --timeout=3s \
|
||||
CMD curl -f http://localhost/ || exit 1
|
||||
@ -1,36 +1,57 @@
|
||||
namespace api
|
||||
#nowarn "20"
|
||||
open System
|
||||
open System.Collections.Generic
|
||||
open System.IO
|
||||
open System.Linq
|
||||
open System.Threading.Tasks
|
||||
open Microsoft.AspNetCore
|
||||
open Microsoft.AspNetCore.Builder
|
||||
open Microsoft.AspNetCore.Hosting
|
||||
open Microsoft.AspNetCore.HttpsPolicy
|
||||
open Microsoft.Extensions.Configuration
|
||||
open Microsoft.Extensions.DependencyInjection
|
||||
open Microsoft.Extensions.Hosting
|
||||
open Microsoft.Extensions.Logging
|
||||
open Microsoft.Extensions.DependencyInjection
|
||||
|
||||
module Program =
|
||||
let exitCode = 0
|
||||
open Blog
|
||||
open Giraffe
|
||||
|
||||
[<EntryPoint>]
|
||||
let main args =
|
||||
// Sources:
|
||||
//https://hamy.xyz/labs/2022-12-simple-fsharp-web-api-giraffe
|
||||
// https://github.com/SIRHAMY/fsharp-giraffe-blog-api-example
|
||||
|
||||
let builder = WebApplication.CreateBuilder(args)
|
||||
(* Web App Configuration *)
|
||||
|
||||
builder.Services.AddControllers()
|
||||
let webApp =
|
||||
let blogDb = new BlogDb()
|
||||
|
||||
let app = builder.Build()
|
||||
let serviceTree = {
|
||||
getBlogDb = fun() -> blogDb
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection()
|
||||
choose[
|
||||
route "/" >=> text "iamanapi"
|
||||
subRoute "/posts"
|
||||
(choose [
|
||||
route "" >=> GET >=> warbler (fun _ ->
|
||||
(getPostsHttpHandler serviceTree))
|
||||
route "/create"
|
||||
>=> POST
|
||||
>=> warbler (fun _ ->
|
||||
(createPostHttpHandler serviceTree))
|
||||
])
|
||||
]
|
||||
|
||||
app.UseAuthorization()
|
||||
app.MapControllers()
|
||||
(* Infrastructure Configuration *)
|
||||
|
||||
app.Run()
|
||||
let configureApp (app : IApplicationBuilder) =
|
||||
app.UseGiraffe (webApp)
|
||||
|
||||
exitCode
|
||||
let configureServices (services : IServiceCollection) =
|
||||
// Add Giraffe dependencies
|
||||
services.AddGiraffe() |> ignore
|
||||
|
||||
[<EntryPoint>]
|
||||
let main _ =
|
||||
Host.CreateDefaultBuilder()
|
||||
.ConfigureWebHostDefaults(
|
||||
fun webHostBuilder ->
|
||||
webHostBuilder
|
||||
.Configure(configureApp)
|
||||
.ConfigureServices(configureServices)
|
||||
|> ignore)
|
||||
.Build()
|
||||
.Run()
|
||||
0
|
||||
@ -1,11 +0,0 @@
|
||||
namespace api
|
||||
|
||||
open System
|
||||
|
||||
type WeatherForecast =
|
||||
{ Date: DateTime
|
||||
TemperatureC: int
|
||||
Summary: string }
|
||||
|
||||
member this.TemperatureF =
|
||||
32.0 + (float this.TemperatureC / 0.5556)
|
||||
@ -1,13 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="WeatherForecast.fs" />
|
||||
<Compile Include="Controllers/WeatherForecastController.fs" />
|
||||
<Compile Include="Database.fs" />
|
||||
<Compile Include="Controllers/PageController.fs" />
|
||||
<Compile Include="Blog.fs" />
|
||||
<Compile Include="Program.fs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Giraffe" Version="6.0.0" />
|
||||
<PackageReference Include="FSharp.Data.SqlClient" Version="2.1.2" />
|
||||
<PackageReference Include="MySqlConnector" Version="2.2.6" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -5,5 +5,8 @@
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
"AllowedHosts": "*",
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "Server=mariadb;Port=33066;Database=portfolio;Uid=root;Pwd=password;"
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,6 +38,21 @@
|
||||
"target": "Package",
|
||||
"version": "[6.0.1, )",
|
||||
"generatePathProperty": true
|
||||
},
|
||||
"FSharp.Data.SqlClient": {
|
||||
"target": "Package",
|
||||
"version": "[2.1.2, )",
|
||||
"generatePathProperty": true
|
||||
},
|
||||
"Giraffe": {
|
||||
"target": "Package",
|
||||
"version": "[6.0.0, )",
|
||||
"generatePathProperty": true
|
||||
},
|
||||
"MySqlConnector": {
|
||||
"target": "Package",
|
||||
"version": "[2.2.6, )",
|
||||
"generatePathProperty": true
|
||||
}
|
||||
},
|
||||
"imports": [
|
||||
@ -58,7 +73,7 @@
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "/usr/lib/dotnet/sdk/6.0.116/RuntimeIdentifierGraph.json"
|
||||
"runtimeIdentifierGraphPath": "/usr/lib/dotnet/sdk/6.0.118/RuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,12 +7,15 @@
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/home/kevin/.nuget/packages/</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/home/kevin/.nuget/packages/</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.0.4</NuGetToolVersion>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.0.5</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="/home/kevin/.nuget/packages/" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<PkgMySqlConnector Condition=" '$(PkgMySqlConnector)' == '' ">/home/kevin/.nuget/packages/mysqlconnector/2.2.6</PkgMySqlConnector>
|
||||
<PkgFSharp_Core Condition=" '$(PkgFSharp_Core)' == '' ">/home/kevin/.nuget/packages/fsharp.core/6.0.1</PkgFSharp_Core>
|
||||
<PkgGiraffe Condition=" '$(PkgGiraffe)' == '' ">/home/kevin/.nuget/packages/giraffe/6.0.0</PkgGiraffe>
|
||||
<PkgFSharp_Data_SqlClient Condition=" '$(PkgFSharp_Data_SqlClient)' == '' ">/home/kevin/.nuget/packages/fsharp.data.sqlclient/2.1.2</PkgFSharp_Data_SqlClient>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,45 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dgSpecHash": "yiQsN9zuNFsQwE5rD1bvmKb2LkPUxTBStlenUjE5prfHVEsOWqez5UPTlQ2uPwnzMX+/02Z8m43BzcokYS9hFg==",
|
||||
"dgSpecHash": "I4tDTnguvZENV8c+kMFM0bQDBX57OyjqKtj9P2K/m/+OaFdmC3Gb4nfrpkzh30ws3CAmgY6Dlgn7Yd6KoBa8wA==",
|
||||
"success": true,
|
||||
"projectFilePath": "/home/kevin/projects/websites/portfolio/api/api.fsproj",
|
||||
"expectedPackageFiles": [
|
||||
"/home/kevin/.nuget/packages/fsharp.core/6.0.1/fsharp.core.6.0.1.nupkg.sha512"
|
||||
"/home/kevin/.nuget/packages/fsharp.core/6.0.1/fsharp.core.6.0.1.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/fsharp.data.sqlclient/2.1.2/fsharp.data.sqlclient.2.1.2.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/giraffe/6.0.0/giraffe.6.0.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/giraffe.viewengine/1.3.0/giraffe.viewengine.1.3.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/microsoft.io.recyclablememorystream/2.2.0/microsoft.io.recyclablememorystream.2.2.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/microsoft.netcore.platforms/2.0.0/microsoft.netcore.platforms.2.0.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/microsoft.netcore.targets/1.1.0/microsoft.netcore.targets.1.1.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/microsoft.win32.registry/4.5.0/microsoft.win32.registry.4.5.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/mysqlconnector/2.2.6/mysqlconnector.2.2.6.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/newtonsoft.json/13.0.1/newtonsoft.json.13.0.1.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/runtime.native.system.data.sqlclient.sni/4.4.0/runtime.native.system.data.sqlclient.sni.4.4.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/runtime.win-arm64.runtime.native.system.data.sqlclient.sni/4.4.0/runtime.win-arm64.runtime.native.system.data.sqlclient.sni.4.4.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/runtime.win-x64.runtime.native.system.data.sqlclient.sni/4.4.0/runtime.win-x64.runtime.native.system.data.sqlclient.sni.4.4.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/runtime.win-x86.runtime.native.system.data.sqlclient.sni/4.4.0/runtime.win-x86.runtime.native.system.data.sqlclient.sni.4.4.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.configuration.configurationmanager/4.5.0/system.configuration.configurationmanager.4.5.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.data.sqlclient/4.5.1/system.data.sqlclient.4.5.1.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.io/4.3.0/system.io.4.3.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.reflection/4.3.0/system.reflection.4.3.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.reflection.emit/4.3.0/system.reflection.emit.4.3.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.reflection.emit.ilgeneration/4.3.0/system.reflection.emit.ilgeneration.4.3.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.reflection.emit.lightweight/4.3.0/system.reflection.emit.lightweight.4.3.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.reflection.primitives/4.3.0/system.reflection.primitives.4.3.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.runtime/4.3.0/system.runtime.4.3.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.runtime.compilerservices.unsafe/6.0.0/system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.security.accesscontrol/4.5.0/system.security.accesscontrol.4.5.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.security.cryptography.protecteddata/4.5.0/system.security.cryptography.protecteddata.4.5.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.security.permissions/4.5.0/system.security.permissions.4.5.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.security.principal.windows/4.5.0/system.security.principal.windows.4.5.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.text.encoding/4.3.0/system.text.encoding.4.3.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.text.encoding.codepages/4.5.0/system.text.encoding.codepages.4.5.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.text.encodings.web/6.0.0/system.text.encodings.web.6.0.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.text.json/6.0.2/system.text.json.6.0.2.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.threading.tasks/4.3.0/system.threading.tasks.4.3.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.threading.tasks.extensions/4.4.0/system.threading.tasks.extensions.4.4.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/system.valuetuple/4.4.0/system.valuetuple.4.4.0.nupkg.sha512",
|
||||
"/home/kevin/.nuget/packages/utf8json/1.3.7/utf8json.1.3.7.nupkg.sha512"
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user