Two weeks ago in F# Weekle #6 2013 I mentioned Don Syme’s “F# + ServiceStack – F# Web Services on any platform in and out of a web server” post. There were two samples of using ServiceStack from F#. One of these examples is given on ServiceStack wiki page in Self Hosting section. It is also detailed in Demis Bellot’s “F# Web Services on any platform in and out of a web server!” post.
Unfortunately, this example is already obsolete. Some time ago, ServiceStack released a brand new API that significantly changed programming approach, especially routing (for details see “ServiceStack’s new API design“). But I am happy to say that you can find an updated example below!
New design is more typed. In the previous version IService‘s methods returned the Object, but now Service returns concrete type that is defined by IReturn<T> interface of request message.
open System open ServiceStack.ServiceHost open ServiceStack.WebHost.Endpoints open ServiceStack.ServiceInterface [<CLIMutable>] type HelloResponse = { Result:string } [<Route("/hello")>] [<Route("/hello/{Name}")>] type Hello() = interface IReturn<HelloResponse> member val Name = "" with get, set type HelloService() = inherit Service() member this.Any (request:Hello) = {Result = "Hello," + request.Name} //Define the Web Services AppHost type AppHost() = inherit AppHostHttpListenerBase("Hello F# Services", typeof<HelloService>.Assembly) override this.Configure container = ignore() //Run it! [<EntryPoint>] let main args = let host = if args.Length = 0 then "http://*:8080/" else args.[0] printfn "listening on %s ..." host let appHost = new AppHost() appHost.Init() appHost.Start host Console.ReadLine() |> ignore 0
For comparison, the previous version is:
open System open ServiceStack.ServiceHost open ServiceStack.WebHost.Endpoints type Hello = { mutable Name: string; } type HelloResponse = { mutable Result: string; } type HelloService() = interface IService with member this.Any (req:Hello) = { Result = "Hello, " + req.Name } //Define the Web Services AppHost type AppHost = inherit AppHostHttpListenerBase new() = { inherit AppHostHttpListenerBase("Hello F# Services", typeof<HelloService>.Assembly) } override this.Configure container = base.Routes .Add<Hello>("/hello") .Add<Hello>("/hello/{Name}") |> ignore //Run it! [<EntryPoint>] let main args = let host = if args.Length = 0 then "http://*:1337/" else args.[0] printfn "listening on %s ..." host let appHost = new AppHost() appHost.Init() appHost.Start host Console.ReadLine() |> ignore 0
Update: An example of ServiceStack New API for F# 2.0 users. F# 2.0 does not have val keyword / auto-properties which were used in the first example.
</pre> open System open ServiceStack.ServiceHost open ServiceStack.WebHost.Endpoints open ServiceStack.ServiceInterface type Project() = let mutable projectID = 0 let mutable projectName = "" let mutable companyName = "" let mutable projectStatus = "" member this.ProjectID with get() = projectID and set(pid) = projectID <-pid member this.ProjectName with get() = projectName and set(pn) = projectName <- pn member this.CompanyName with get() = companyName and set(cn) = companyName <- cn member this.ProjectStatus with get() = projectStatus and set(ps) = projectStatus <-ps type ProjectResponse() = let mutable projects = List.empty<Project> member this.Projects with get() = projects and set(pr) = projects <- pr [<Route("/Project/{ProjectName}")>] type ProjectRequest() = let mutable projectName = "" interface IReturn<ProjectResponse> member this.ProjectName with get() = projectName and set(n) = projectName <- n type ProjectService() = inherit Service() member this.Any (request:ProjectRequest) = ProjectResponse( Projects = [Project(ProjectName=request.ProjectName, ProjectID=1, CompanyName="A")]) //Define the Web Services AppHost type AppHost() = inherit AppHostHttpListenerBase("Project F# Services", typeof<ProjectService>.Assembly) override this.Configure container = ignore() //Run it! [<EntryPoint>] let main args = let host = if args.Length = 0 then "http://*:8080/" else args.[0] printfn "listening on %s ..." host let appHost = new AppHost() appHost.Init() appHost.Start host Console.ReadLine() |> ignore 0 <pre>
There seems to be a typo on line 11 in the word “Response”:
“interface IReturn”
Minor detail, but it could cause confusion for copy/pasters.
Otherwise thank you for the example 🙂
Thanks. Fixed. This is a strange typo… =)
Hey, the response types are made mutable so that they can work with the ServiceStack.Text serializer I presume? You can also mark them with [CLIMutable] and make them compatible with ServiceStack.Text.
Yes, thanks. Actually, good idea! Sample was updated.
Hi
I am trying to run New API code in F# .Old code works fine but i get “Unexpected keyword ‘val’ in member definition” (Line 13 in code above)
Can you please suggest me what is that not right ?
I have a service running (New API) with C# . I want to convert this to F#
Thanks in advance.
Can you clarify what version of F# and .NET you use?
The ‘val’ keyword is a part of F# 3.0 (which ships with Visual Studio 2012)
If you are using older version of F# you should replace Hello class definition to the following
type Hello() =
let mutable name = ""
interface IReturn<HelloResponse>
member this.Name with get() = name
and set(n) = name <- n
Hi
Thanks for the quick response .
I am using VS2010 Ultimate and I have VS2012 Web Express ( i am not sure if i can use F# there)
The code you sent also doesn’t work.This has no Response type in IReturn and gives other errors.
Here is my code i want to port from c# to F# (With a list of project object) Can you please explain how i can write that in F#2.0 and what would be best way to make F# 3.0 up and running
[Route(“/Project/{ProjectName}”)]
public class ProjectRequest : IReturn
{
public string ProjectName { get; set; }
}
public class Project
{
public int ProjectID { get; set; }
public string ProjectName { get; set; }
public string CompanyName { get; set; }
public string ProjectStatus { get; set; }
}
public class ProjectResponse : IReturn<List>
{
public ProjectResponse()
{
Projects = new List();
}
public List Projects { get; set; }
}
>>The code you sent also doesn’t work.This has no Response type in IReturn and gives other errors.
Sorry, it is comment formatting issue (already fixed)
>> I have VS2012 Web Express ( i am not sure if i can use F# there)
You can! http://blogs.msdn.com/b/fsharpteam/archive/2012/09/12/announcing-the-release-of-f-tools-for-visual-studio-express-2012-for-web.aspx
>> what would be best way to make F# 3.0 up and running
Please look at available options: http://fsharp.org/use/windows/
>> Can you please explain how i can write that in F#2.0
You code should look like this: https://gist.github.com/sergey-tihon/5343737
Thanks alot . I will try this and will bother you again in case i have more question 😉
thanks again.
Your code works like a charm. I hope with F# 3.0 code will look more cleaner .
You likely wont need all that boilerplate for the F# 2.0 solution and can benefit from setting ServiceStack’s text serializers to serialize public fields with:
JsConfig.IncludePublicFields = true;
HI
I have upgrade my service to F# 3.0
I was using Dapper a lot in Service Stack C# service .What would be the best option to use it in F# solution?
Do i have to use it via creating a seprate c# assembly and call in from F# ?? Or there are better solution.
Thanks for your previous help again.I have almost reduced my service code to over 50% less line of code and in almost no time 🙂
F# should be good with Dapper too, I think that you can rewrite it with F# if you wish – http://stackoverflow.com/questions/9364480/dapper-dot-net-query-in-f
BTW, Dapper use F# PowerPack under the hood 😉 // https://code.google.com/p/dapper-dot-net/source/browse/#git%2Fpackages%2FFSPowerPack.Community.2.0.0.0
thanks , i will have a look to it. may be i can rewrite dapper completely in F#
Hi
I could look for the possibility to transform dapper into F# but this could take a while .
I read little about FSSQL but could find any analysis about performance etc ..
http://d4dilip.wordpress.com/
Unfortunately it seems the latest NUGET version of ServiceStack, that I installed using Install-package ServiceStack.Server, does not seem to like this code at all…. Here are the errors.
I’m using VS2013, any ideas?
Program.fs(2,19): error FS0039: The namespace ‘ServiceHost’ is not defined
Program.fs(3,19): error FS0039: The namespace ‘WebHost’ is not defined
Program.fs(4,19): error FS0039: The namespace ‘ServiceInterface’ is not defined
Program.fs(9,3): error FS0039: The type ‘Route’ is not defined
Program.fs(10,3): error FS0039: The type ‘Route’ is not defined
Program.fs(12,15): error FS0039: The type ‘IReturn’ is not defined
Program.fs(12,15): error FS0887: The type ‘obj’ is not an interface type
Program.fs(12,15): error FS0039: The type ‘IReturn’ is not defined
Program.fs(12,15): error FS0039: The type ‘IReturn’ is not defined
Program.fs(12,15): error FS0908: This type is not an interface type
Program.fs(16,13): error FS0039: The type ‘Service’ is not defined
Program.fs(16,13): error FS0039: The type ‘Service’ is not defined
Program.fs(16,13): error FS0039: The type ‘Service’ is not defined
Program.fs(22,13): error FS0039: The type ‘AppHostHttpListenerBase’ is not defined
Program.fs(22,13): error FS0039: The type ‘AppHostHttpListenerBase’ is not defined
Program.fs(23,19): error FS0855: No abstract or interface member was found that corresponds to this override
Program.fs(22,13): error FS0039: The type ‘AppHostHttpListenerBase’ is not defined
Program.fs(31,13): error FS0039: The field, constructor or member ‘Init’ is not defined
Program.fs(32,13): error FS0039: The field, constructor or member ‘Start’ is not defined
Hmm, ok, so if I remove all of the “open ServiceStack.*” imports at the top and just replace them with a single “open ServiceStack”, then it will compile and run but as soon as it gets to this line:
inherit AppHostHttpListenerBase(“Hello F# Services”, typeof.Assembly)
it bombs out with
An unhandled exception of type ‘System.TypeLoadException’ occurred in ServiceStack.dll
Additional information: Method ‘ExecuteMessage’ in type ‘ServiceStack.Host.ServiceController’ from assembly ‘ServiceStack, Version=4.0.9.0, Culture=neutral, PublicKeyToken=null’ does not have an implementation.
Hi, @Mattp, you must have updated servicestack after getting template. In template I have used 3.71 version. Which was still under MIT. If you update to 4.X it is paid version. Here is pricing details https://servicestack.net/pricing.
And for other template, including this one updated. Here is fork of community templates https://github.com/kunjee17/FSharpCommunityTemplates , I am waiting for my pull request to getting accepted though. But still if you have VS2013 sdk installed you can build and install VSIX.
Error you are facing is because of breaking changes in v4. If you want to use MIT license library then please do no update nuget. If you are want to go with v4 then let me know. I will share v4 projects with you.
Let me know the details.
I have update my repo with V4 sample as well. I don’t know it will be coming soon to templates. As everything < v4 are under MIT license, so normally people are preferring that. That is why I created templates using that only. Here is link to my repo https://github.com/kunjee17/ServiceStackFSharp have a look at that and let me know if you need any help over there.