F#+WCFでRESTfulなサービスをこしらえる

GETについて色々


昨日のソースコードに色々とHTTP GETで呼び出すメソッドを追加して、動きを確認してみました。

// F# の詳細 (http://fsharp.net)

#light  
namespace FSharpWCF  
  
open System  
open System.Runtime.Serialization  
open System.ServiceModel  
open System.ServiceModel.Web

[<DataContract>]
type MyData(n:string) =
  let mutable name = n
  [<DataMember(Name="NAME")>]
  member this.Name with get() = name and set(value) = name <- value
  
[<ServiceContract>]  
type IGetDataService = interface   
  [<WebGet(UriTemplate="temp/{value}")>]  
  [<OperationContract>]  
  abstract GetData : value:string -> string  
  [<WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate="temp2/{value}")>]  
  [<OperationContract>]  
  abstract GetData2 : value:string -> string
  [<WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate="temp3/{value}")>]  
  [<OperationContract>]  
  abstract GetData3 : value:string -> MyData
  [<WebInvoke(Method="GET", ResponseFormat = WebMessageFormat.Json, UriTemplate="temp4/{value}")>]  
  [<OperationContract>]  
  abstract GetData4 : value:string -> MyData[]  
end  
  
type GetDataService() =   
  interface IGetDataService with  
    member this.GetData value =  
      sprintf "You entered: %s" value 
    member this.GetData2 value =  
      sprintf "You entered: %s" value 
    member this.GetData3 value =  
      new MyData(value)
    member this.GetData4 value =  
      [new MyData(value); new MyData("foo"); new MyData("bar")]
      |> List.toArray
  • F#は基本的に前方参照が出来ないので、自分で定義したデータ型を返す時は、ServiceContractよりも前に書く必要がある
  • 配列も返す事が可能。XML,Jsonに適切に変換される

ちなみに配列を返すのではなくリストを返すように書き換えるとどうなるかというと、

{"head":{"NAME":"foobar"},"tail":{"head":{"NAME":"foo"},"tail":{"head":{"NAME":"bar"},"tail":{"head":null,"tail":null}}}}

こんな風に通好みなJsonが返ってきます。シブ過ぎる。

  • WebGetとWebInvoke属性があり、WebGetはHTTP GETに対応していて、WebInvokeはMethodで指定したHTTPMethodが呼ばれる

あと、Jsonを使用するサービスでいちいちJsonを指定するのが面倒くさかったら、
configファイルのendpointbehaviorsに

      <endpointBehaviors>
        <behavior name="Web">
          <webHttp defaultOutgoingResponseFormat="Json" />
        </behavior>
      </endpointBehaviors>

を指定すればデフォルトでJsonとなります(デフォルトはXML)。