WebSharper
By Loïc Denuzière on Wednesday, July 22, 2015 — 8 comments

WebSharper 3.3 released with client-side JSON serializationCore team

We are happy to announce the availability of WebSharper 3.3, which you can download here. The main highlight of this release is the addition of JSON serialization functions for client-side code.

The format used for this serialization is identical to the format used by inferred Sitelets. This means that you can now easily craft your request data on the client, perform an AJAX call to your Sitelets API, and parse the reply, all of this type-safely!

For example, for a website defined as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
open WebSharper
open WebSharper.Sitelets

type EndPoints =
    | [<EndPoint "POST /article"; Json "article">]
      PostArticle of article: Article
and Article = { title: string; body: string }

[<Website>]
let app = Sitelet.Infer <| function
    | PostArticle article ->
        let articleId = ApplicationLogic.SaveArticle article
        Content.JsonContent (fun _ -> articleId)

You can invoke the REST endpoint POST /article from the client-side like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[<JavaScript>]
module Client =
    open WebSharper.JavaScript
    open WebSharper.JQuery

    /// General function to send an AJAX request with a body.
    let Ajax (method: string) (url: string) (serializedData: string) : Async<string> =
        Async.FromContinuations <| fun (ok, ko, _) ->
            JQuery.Ajax(
                JQuery.AjaxSettings(
                    Url = url,
                    Type = As<JQuery.RequestType> method,
                    ContentType = "application/json",
                    DataType = JQuery.DataType.Text,
                    Data = serializedData,
                    Success = (fun (result, _, _) -> ok (result :?> string)),
                    Error = (fun (jqXHR, _, _) -> ko (System.Exception(jqXHR.ResponseText)))))
            |> ignore

    /// Use Json.Serialize and Deserialize to send and receive data to and from the server.
    let PostBlogArticle (article: Article) : Async<int> =
        async { let! response = Ajax "POST" "/article" (Json.Serialize article)
                return Json.Deserialize<int> response }

This new API is located in the module WebSharper.Json. Its only limitation compared with Sitelets is that the [<DateTimeFormat>] attribute is currently ignored, as JavaScript doesn't have built-in datetime formatting capabilities. We might consider using an external library such as moment.js for this purpose in the future.

Future plans

We have lots of exciting things to come in WebSharper. Here is what you can expect from upcoming releases:

  • F# 4.0 support, including JavaScript proxies for the new collection library functions.
  • A new, cleaner HTML combinator syntax. This syntax will supersede the current Html.Server, Html.Client and UI.Next.HTML with a unique type. This means that the same HTML code will be usable both from the server and client side.

Happy coding!

  • Paweł Stadnicki

    Great stuff! Actually it is what I need now!.

    PS: What do you think about moving json serialization to ajax computation builder? :

    1
    2
    
    ajax { let! response = post "/article" article
                    return  response }
    • loic.denuziere

      There isn't really a need for a separate computation expression, because this post can simply return an Async<'T>. But it is true that we can leave the task of serializing and deserializing to this function, and we will probably be adding such functionality soon.

  • Brian Berns

    Is there more documentation on using AJAX from WebSharper? The function above is a bit opaque to this newbie. For example, the "method" argument is ignored and the RequestType is hard-coded to POST. Is this deliberate?

    • loic.denuziere

      No, this is a mistake, thanks for noticing it! It is now fixed.

      We have been thinking about, and probably will soon be adding a library function that does essentially the same thing as the function in this sample. But if you want to understand it more, it is essentially a call to jQuery.ajax() with a settings object: the JQuery.AjaxSettings(...) call is compiled to a plain JavaScript object creation, passed as the settings argument documented here.

    • davidgrenier

      Brian, I just wanted to make sure that WebSharper handles ajax calls transparently (static typing/serialization/wiring url) through RPC if you are calling server side function on a site built with WebSharper.

      I presume the use of this feature is whenever you are calling another endpoint/service on the same domain or reaching out to an http serviced database say Event Store.

  • bananasareyellow

    We have lots of exciting things to come in WebSharper. Here is what you can expect from upcoming releases ...

    When is support for F# 4.0 coming? I downloaded VS 2015 on Monday (I don't hang about) and I'm looking forward to moving everything to .NET 4.6 and F# 4.0.

    • adam.granicz

      I would definitely wait with .NET 4.6 :) Other than that, WebSharper 3.4 has just been published with support for F# 4.0.

  • Andrew Jones

    I'm getting the error "Serialize: Type not supported" during WebSharper Compilation, but only when using MSBuild only (works with VS). I've created an issue on github: https://github.com/intellifactory/websharper/issues/468