Skip to content

Commit

Permalink
Fix dotnet-websharper#430: Inferred sitelets: Allow specifying the me…
Browse files Browse the repository at this point in the history
…thod in EndPoint
  • Loading branch information
Tarmil committed Jun 12, 2015
1 parent 363af9a commit 5ab9002
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 62 deletions.
10 changes: 9 additions & 1 deletion src/sitelets/WebSharper.Sitelets/ActionEncoding.fs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ type Reflection.UnionCaseInfo with
match this.GetCustomAttributes aT with
| [| :? CompiledNameAttribute as attr |] -> attr.CompiledName
| _ -> this.Name
s.TrimStart('/')
s.[s.IndexOf('/') + 1 ..]

let flags =
System.Reflection.BindingFlags.Public
Expand Down Expand Up @@ -601,6 +601,14 @@ let getUnionCaseMethods (c: Reflection.UnionCaseInfo) =
:?> System.Collections.ObjectModel.ReadOnlyCollection<
System.Reflection.CustomAttributeTypedArgument>
|> Seq.map (fun a -> Some (a.Value :?> string))
elif cad.Constructor.DeclaringType = typeof<CompiledNameAttribute> then
let s = cad.ConstructorArguments.[0].Value :?> string
match s.IndexOf '/' with
| -1 -> Seq.empty
| i ->
s.[..i - 1].Split([|',';' '|],
StringSplitOptions.RemoveEmptyEntries)
|> Seq.map Some
else Seq.empty)
if Seq.isEmpty s then Seq.singleton None else s

Expand Down
122 changes: 61 additions & 61 deletions tests/WebSharper.Sitelets.Tests/Api.fs
Original file line number Diff line number Diff line change
@@ -1,47 +1,47 @@
// $begin{copyright}
//
// This file is part of WebSharper
//
// Copyright (c) 2008-2014 IntelliFactory
//
// Licensed under the Apache License, Version 2.0 (the "License"); you
// may not use this file except in compliance with the License. You may
// obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License.
//
// $end{copyright}

namespace WebSharper.Sitelets.Tests

open System
open System.Collections.Generic
open WebSharper
open WebSharper.Sitelets

/// This module implements the tutorial REST API from https://websharper.com/tutorials/rest-api
/// It's a full CRUD application maintaining a basic in-memory database of people.
module Api =

/// The type of actions, ie. REST API entry points.
// $begin{copyright}
//
// This file is part of WebSharper
//
// Copyright (c) 2008-2014 IntelliFactory
//
// Licensed under the Apache License, Version 2.0 (the "License"); you
// may not use this file except in compliance with the License. You may
// obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License.
//
// $end{copyright}

namespace WebSharper.Sitelets.Tests

open System
open System.Collections.Generic
open WebSharper
open WebSharper.Sitelets

/// This module implements the tutorial REST API from https://websharper.com/tutorials/rest-api
/// It's a full CRUD application maintaining a basic in-memory database of people.
module Api =

/// The type of actions, ie. REST API entry points.
type Action =
/// GET /person?id=123
| [<Method "GET"; EndPoint "/person"; Query "id">]
| [<EndPoint "PATCH GET /person"; Query "id">]
GetPerson of id: int
/// POST /person (with JSON body)
| [<Method "POST"; EndPoint "/person"; Json "personData">]
| [<EndPoint "POST /person"; Json "personData">]
PostPerson of personData: PersonData
/// PUT /person?id=123 (with JSON body)
| [<Method "PUT"; EndPoint "/person"; Query "id"; Json "personData">]
| [<EndPoint "PUT /person"; Query "id"; Json "personData">]
PutPerson of id: int * personData: PersonData
/// DELETE /person?id=123
| [<Method "DELETE"; EndPoint "/person"; Query "id">]
| [<EndPoint "DELETE /person"; Query "id">]
DeletePerson of id: int

/// Data about a person. Used both for storage and JSON parsing/writing.
Expand All @@ -52,8 +52,8 @@ module Api =
[<DateTimeFormat "yyyy-MM-dd">] born: System.DateTime
/// Since this is an option, this field is only present in JSON for Some value.
[<DateTimeFormat "yyyy-MM-dd">] died: option<System.DateTime> }

/// Type used for all JSON responses to indicate success or failure.

/// Type used for all JSON responses to indicate success or failure.
[<NamedUnionCases "result">]
type Result<'T> =
/// JSON: {"result": "success", /* fields of 'T... */}
Expand All @@ -63,14 +63,14 @@ module Api =

/// Result value for PostPerson.
type Id = { id : int }


module private ApplicationLogic =

/// The people database.
let people = new Dictionary<int, PersonData>()
/// The highest id used so far, incremented each time a person is POSTed.
let lastId = ref 0


let getPerson (id: int) : Result<PersonData> =
lock people <| fun () ->
match people.TryGetValue(id) with
Expand Down Expand Up @@ -98,7 +98,7 @@ module Api =
people.Remove(id) |> ignore
Success None
| false, _ -> Failure "Person not found."


let ApiContent (action: Action) : Content<Action> =
match action with
| GetPerson id ->
Expand All @@ -111,23 +111,23 @@ module Api =
Content.JsonContent <| fun ctx -> ApplicationLogic.deletePerson id

let Sitelet = Sitelet.Infer ApiContent

// Pre-fill the database with a few people.
do Seq.iter (ApplicationLogic.postPerson >> ignore) [
{ firstName = "Alonzo"
lastName = "Church"
born = DateTime(1903, 6, 14)
died = Some(DateTime(1995, 8, 11)) }
{ firstName = "Alan"
lastName = "Turing"
born = DateTime(1912, 6, 23)
died = Some(DateTime(1954, 6, 7)) }
{ firstName = "Bertrand"
lastName = "Russell"
born = DateTime(1872, 5, 18)
died = Some(DateTime(1970, 2, 2)) }
{ firstName = "Noam"
lastName = "Chomsky"
born = DateTime(1928, 12, 7)
died = None }
]

// Pre-fill the database with a few people.
do Seq.iter (ApplicationLogic.postPerson >> ignore) [
{ firstName = "Alonzo"
lastName = "Church"
born = DateTime(1903, 6, 14)
died = Some(DateTime(1995, 8, 11)) }
{ firstName = "Alan"
lastName = "Turing"
born = DateTime(1912, 6, 23)
died = Some(DateTime(1954, 6, 7)) }
{ firstName = "Bertrand"
lastName = "Russell"
born = DateTime(1872, 5, 18)
died = Some(DateTime(1970, 2, 2)) }
{ firstName = "Noam"
lastName = "Chomsky"
born = DateTime(1928, 12, 7)
died = None }
]

0 comments on commit 5ab9002

Please sign in to comment.