Skip to content

Instantly share code, notes, and snippets.

@gistlyn
Last active Feb 9, 2022
Embed
What would you like to do?
F# Empty .NET 6 ServiceStack App
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TypeScriptToolsVersion>latest</TypeScriptToolsVersion>
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ServiceStack" Version="6.*" />
</ItemGroup>
<ItemGroup>
<Compile Include="ServiceModel\Hello.fs" />
<Compile Include="ServiceInterface\MyServices.fs" />
<Compile Include="Startup.fs" />
<Compile Include="Program.fs" />
</ItemGroup>
</Project>
namespace fsharp
open System
open System.Collections.Generic
open System.IO
open System.Linq
open System.Threading.Tasks
open Microsoft.AspNetCore
open Microsoft.AspNetCore.Hosting
open Microsoft.Extensions.Configuration
open Microsoft.Extensions.Hosting
open Microsoft.Extensions.Logging
open ServiceStack
module Program =
let exitCode = 0
let CreateHostBuilder args =
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(fun webBuilder ->
ModularExtensions.UseModularStartup<Startup>(webBuilder)
|> ignore)
[<EntryPoint>]
let main args =
CreateHostBuilder(args).Build().Run()
exitCode
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "https://localhost:5001/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"MyApp": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001/"
}
}
}
namespace MyApp.ServiceInterface
open System
open ServiceStack
open MyApp.ServiceModel
type HelloService() =
inherit Service()
member this.Any (req:Hello) =
HelloResponse(Result = "Hello, " + req.Name)
namespace MyApp.ServiceModel
open System
open System.Collections
open System.Collections.Generic
open System.Runtime.Serialization
open ServiceStack
open ServiceStack.DataAnnotations
[<AllowNullLiteral>]
type HelloResponse() =
member val Result:String = null with get,set
[<Route("/hello")>]
[<Route("/hello/{Name}")>]
[<AllowNullLiteral>]
type Hello() =
interface IReturn<HelloResponse>
member val Name:String = null with get,set
namespace fsharp
open System
open Microsoft.AspNetCore.Builder
open Microsoft.AspNetCore.Hosting
open Microsoft.AspNetCore.Http
open Microsoft.Extensions.DependencyInjection
open Microsoft.Extensions.Hosting
open Microsoft.Extensions.Configuration
open Funq
open ServiceStack
open ServiceStack.Configuration
open ServiceStack.Text
open MyApp.ServiceInterface
type AppHost =
inherit AppHostBase
new() = { inherit AppHostBase("My App", typeof<HelloService>.Assembly) }
override this.Configure(container: Container): unit =
base.SetConfig
(HostConfig(UseSameSiteCookies = Nullable true, DebugMode = base.HostingEnvironment.IsDevelopment()))
|> ignore
type Startup(Configuration: IConfiguration) =
inherit ModularStartup()
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
member this.ConfigureServices(services: IServiceCollection) = ()
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
member this.Configure(app: IApplicationBuilder, env: IWebHostEnvironment) =
if env.IsDevelopment()
then app.UseDeveloperExceptionPage() |> ignore
app.UseServiceStack(new AppHost(AppSettings = NetCoreAppSettings(Configuration)))
|> ignore
<html>
<head>
<title>My App</title>
<style>
body { padding: 1em 1em 0 1em; }
body, input[type=text] { font: 32px/36px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif }
input { padding:.25em .5em; margin-right:.5em; }
a { color: #007bff }
#result { display:inline-block;color:#28a745; }
pre { background: #f1f1f1; padding: 1em; }
</style>
</head>
<body>
<h2><a href="/ui/Hello">Hello</a> API</h2>
<input type="text" id="txtName" onkeyup="callHello(this.value)">
<div id="result"></div>
<script src="/js/require.js"></script>
<script src="/js/servicestack-client.js"></script>
<script src="/types/js"></script>
<script>
var { JsonServiceClient, Hello } = exports
var client = new JsonServiceClient();
function callHello(name) {
client.get(new Hello({ name }))
.then(function(r) {
document.getElementById('result').innerHTML = r.result;
});
}
callHello(document.querySelector('#txtName').value = 'World')
</script>
<div style="font-size:20px;line-height:26px">
<h3>View in API Explorer</h3>
<ul>
<li>
<a href="/ui/Hello">Call API</a>
</li>
<li>
<a href="/ui/Hello?tab=details">View API Details</a>
</li>
<li>
<a href="/ui/Hello?tab=code">Browse API Source Code</a>
</li>
</ul>
<h3>Using JsonServiceClient in Web Pages</h3>
<p>
The easiest way to call your APIs in a webpage is to include your JavaScript DTOs <b>/types/js</b> and built-in
UMD <a href="https://docs.servicestack.net/servicestack-client-umd">@servicestack/client</a> library:
</p>
<pre>&lt;script src="/js/require.js"&gt;&lt;/script&gt;
&lt;script src="/js/servicestack-client.js"&gt;&lt;/script&gt;
&lt;script src="/types/js"&gt;&lt;/script&gt;</pre>
<p>
We can then import and use the library and DTO types:
</p>
<pre>var { JsonServiceClient, Hello } = exports
var client = new JsonServiceClient()
client.api(new Hello({ name }))
.then(function(api) {
if (api.succeeded)
console.log(api.response)
})
</pre>
<h3>Using @servicestack/client in npm projects</h3>
<p>
Update your App's
<a href="https://docs.servicestack.net/typescript-add-servicestack-reference">TypeScript DTOs</a> and
compile to JS (requires <a href="https://www.typescriptlang.org/download">TypeScript</a>):
</p>
<pre>$ x scripts dtos</pre>
<h3>Including @servicestack/client &amp; Typed DTOs</h3>
<p>
Where you'll be able to use your APIs typed DTOs with ServiceStack's generic **JsonServiceClient**
</p>
<pre>$ npm install @servicestack/client</pre>
<pre>import { JsonServiceClient } from '@servicestack/client'
import { Hello } from './dtos'
let client = new JsonServiceClient()
let api = await client.api(new Hello({ name }))
if (api.succeeded)
console.log(api.response.result)
</pre>
<p>
Typed DTOs generated using
<a href="https://docs.servicestack.net/typescript-add-servicestack-reference">TypeScript Add ServiceStack Reference</a>
</p>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment