frank-fs / frank Goto Github PK
View Code? Open in Web Editor NEWF# computation expressions for defining HTTP resources and configuring IWebHostBuilder.
License: MIT License
F# computation expressions for defining HTTP resources and configuring IWebHostBuilder.
License: MIT License
While similar to the implementation in the Snap Framework, the state monad adds to the complexity of the implementation. Is it necessary? Is there a better abstraction, such as pure Async or Continuation workflows?
I've circumvented the buildng on mono issue by getting all of the DLLs with NuGet and building the SelfHosting sample. It does bring up the submit button but all contact/ routes don't return anything. I wonder whether async works as expected on Mono 3.0. What's the expected behavior on Windows?
Ultimately, the benefit from something like this should be to define one's own protocol that happens to use HTTP. I think it would be beneficial to show a CE using HTML or PHTAL that provides state transitions in the results.
Microsoft has moved the SelfHost namespace to its own nuget and it seems they have broken the dependencies of Frank by doing so.
Rather than build directly on System.Net.Http, Frank should support additional components written on top of the Web API infrastructure. However, it should support the functional style.
I've already started working on getting this to depend solely on Frack, but it needs to be completed. In particular,
As is the nugget version used when creating the package.
How do I build on Mono? The mono-build.sh fails out of the box. Tweaking paths a bit still doesn't do it. Also tried FAKE from ./packages and that emits such a horrific stack that the whole idea of .NET comes into question. :)
Though the RouteData
contains the value, the casting no longer appears to work.
I'm considering re-purposing this library to primarily work with Azure Functions. The HTTP Azure Function templates use the System.Net.Http
types HttpRequestMessage
and HttpResponseMessage
, which Frank also uses. This makes Frank a natural option to build HTTP Azure Functions in F#. Perhaps this will breathe new life into this little library.
@enricosada, would you mind helping me work through this transition?
Are the HttpRequestMessage and HttpResponseMessage types from the WCF Web API suitable? Is something else required?
[1 sec] Reading assembly: C:\Users\ryan\Code\frank\docs\tools../../bin\Frank.dll
[1 sec] Parsing assembly
Microsoft.FSharp.Compiler.ErrorLogger+UnresolvedPathReferenceNoRange: Exception of type 'Microsoft.FSharp.Compiler.Error
Logger+UnresolvedPathReferenceNoRange' was thrown.
at Microsoft.FSharp.Compiler.Tast.CcuThunk.EnsureDerefable(String[] requiringPath) in C:\GitHub\fsharp\FSharp.Compile
r.Service\src\fsharp\tast.fs:line 3044
at Microsoft.FSharp.Compiler.Tast.NonLocalEntityRef.TryDeref(Boolean canError) in C:\GitHub\fsharp\FSharp.Compiler.Se
rvice\src\fsharp\tast.fs:line 2459
at Microsoft.FSharp.Compiler.Tast.EntityRef.get_Deref() in C:\GitHub\fsharp\FSharp.Compiler.Service\src\fsharp\tast.f
s:line 2544
at Microsoft.FSharp.Compiler.Tastops.stripTyEqnsA(TcGlobals g, Boolean canShortcut, TType ty) in C:\GitHub\fsharp\FSh
arp.Compiler.Service\src\fsharp\tastops.fs:line 616
at Microsoft.FSharp.Compiler.Tastops.typeEnc(TcGlobals g, FSharpList1 gtpsType, FSharpList
1 gtpsMethod, TType ty) i
n C:\GitHub\fsharp\FSharp.Compiler.Service\src\fsharp\tastops.fs:line 6685
at Microsoft.FSharp.Primitives.Basics.List.mapToFreshConsTail[a,b](FSharpList1 cons, FSharpFunc
2 f, FSharpList`1 x)
at Microsoft.FSharp.Primitives.Basics.List.map[T,TResult](FSharpFunc2 mapping, FSharpList
1 x)
at Microsoft.FSharp.Compiler.Tastops.XmlDocArgsEnc(TcGlobals g, FSharpList1 gtpsType, FSharpList
1 gtpsMethod, FShar
pList1 argTs) in C:\GitHub\fsharp\FSharp.Compiler.Service\src\fsharp\tastops.fs:line 6736 at Microsoft.FSharp.Compiler.Tastops.XmlDocSigOfVal(TcGlobals g, String path, Val v) in C:\GitHub\fsharp\FSharp.Compi ler.Service\src\fsharp\tastops.fs:line 6780 at Microsoft.FSharp.Compiler.SourceCodeServices.ItemDescriptionsImpl.GetXmlDocSigOfValRef(TcGlobals g, EntityRef tcre f, ValRef vref) in C:\GitHub\fsharp\FSharp.Compiler.Service\src\fsharp\vs\ServiceDeclarations.fs:line 295 at Microsoft.FSharp.Compiler.SourceCodeServices.FSharpMemberFunctionOrValue.get_XmlDocSig() in C:\GitHub\fsharp\FShar p.Compiler.Service\src\fsharp\vs\Symbols.fs:line 1278 at FSharp.MetadataFormat.Reader.tryReadMember(ReadingContext ctx, MemberKind kind, FSharpMemberFunctionOrValue memb) in D:\code\FSharp.Formatting\src\FSharp.MetadataFormat\Main.fs:line 571 at [email protected](FSharpMemberFunctionOrValue memb) in D:\code\FSharp.Formatting \src\FSharp.MetadataFormat\Main.fs:line 584 at Microsoft.FSharp.Collections.IEnumerator.choose@154.System-Collections-IEnumerator-MoveNext() at Microsoft.FSharp.Collections.SeqModule.ToList[T](IEnumerable
1 source)
at [email protected](String cat, IDictionary2 cmd, Comment comment) in D:\code\FSha rp.Formatting\src\FSharp.MetadataFormat\Main.fs:line 705 at FSharp.MetadataFormat.Reader.readCommentsInto[a](ReadingContext ctx, String xmlDoc, FSharpFunc
2 f) in D:\code\FSh
arp.Formatting\src\FSharp.MetadataFormat\Main.fs:line 557
at FSharp.MetadataFormat.Reader.readModule(ReadingContext ctx, FSharpEntity modul) in D:\code\FSharp.Formatting\src\F
Sharp.MetadataFormat\Main.fs:line 701
at [email protected](ReadingContext ctx, FSharpEntity modul) in D:\code\FSh
arp.Formatting\src\FSharp.MetadataFormat\Main.fs:line 644
at Microsoft.FSharp.Collections.IEnumerator.choose@154.System-Collections-IEnumerator-MoveNext()
at Microsoft.FSharp.Collections.SeqModule.ToList[T](IEnumerable1 source) at FSharp.MetadataFormat.Reader.readModulesAndTypes(ReadingContext ctx, IEnumerable
1 entities) in D:\code\FSharp.For
matting\src\FSharp.MetadataFormat\Main.fs:line 646
at FSharp.MetadataFormat.Reader.readNamespace(ReadingContext ctx, String ns, IEnumerable1 entities) in D:\code\FShar p.Formatting\src\FSharp.MetadataFormat\Main.fs:line 722 at [email protected](Tuple
2 tupledArg) in D:\code\FSharp.Formatting\src\FSharp.Meta
dataFormat\Main.fs:line 746
at [email protected](b& )
at Microsoft.FSharp.Collections.IEnumerator.MapEnumerator1.System-Collections-IEnumerator-MoveNext() at Microsoft.FSharp.Collections.SeqModule.ToList[T](IEnumerable
1 source)
at FSharp.MetadataFormat.Reader.readAssembly(FSharpAssembly assembly, Boolean publicOnly, String xmlFile, FSharpOptio
n1 sourceFolderRepo, FSharpFunc
2 urlRangeHighlight, Boolean markDownComments) in D:\code\FSharp.Formatting\src\FSharp.
MetadataFormat\Main.fs:line 741
at <StartupCode$FSharp-MetadataFormat>.$[email protected](IEnumerable1& next) in D:\code\FSharp.For matting\src\FSharp.MetadataFormat\Main.fs:line 0 at Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase
1.MoveNextImpl()
at Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase1.System-Collections-IEnumerator-MoveNext() at Microsoft.FSharp.Collections.SeqModule.ToList[T](IEnumerable
1 source)
at FSharp.MetadataFormat.MetadataFormat.Generate(FSharpList1 dllFiles, String outDir, IEnumerable
1 layoutRoots, FSh
arpOption1 parameters, FSharpOption
1 namespaceTemplate, FSharpOption1 moduleTemplate, FSharpOption
1 typeTemplate, FS
harpOption1 xmlFile, FSharpOption
1 sourceRepo, FSharpOption1 sourceFolder, FSharpOption
1 publicOnly, FSharpOption1 libDirs, FSharpOption
1 otherFlags, FSharpOption1 markDownComments, FSharpOption
1 urlRangeHighlight) in D:\code\FSharp
.Formatting\src\FSharp.MetadataFormat\Main.fs:line 853
at <StartupCode$FSI_0002>.$FSI_0002.main@() in C:\Users\ryan\Code\frank\docs\tools\generate.fsx:line 93
Stopped due to error
How does this lib compare to the other f# web combinator libs?
Best I can tell, I moved up to .NET 4.5 so that I could use Frank as a compiled assembly with the latest version of Web API. Same problem occurred with WebApiContrib, as well.
Rather than just accepting a (HttpMethod * HttpApplication) list
, we could allow the use of a F# record with defaults, i.e.:
type Resource =
{
Get : HttpApplication
Head : HttpApplication
Post : HttpApplication
Put : HttpApplication
Delete : HttpApplication
Trace : HttpApplication
Options : HttpApplication
}
with
Defaults =
{
Get = ``Method Not Allowed``
Head = ``Method Not Allowed``
Post = ``Method Not Allowed``
Put = ``Method Not Allowed``
Delete = ``Method Not Allowed``
Trace = ``Method Not Allowed``
Options = ``Method Not Allowed``
}
Routing is still a half-baked idea. Function composition is currently implemented to handle this, but it's not very flexible. ApiRouter is a possible base, but taking that further and using pure functions would result in a Discriminated Union for defining a Sitemap. That would allow a way to provide both verifiable, static routes and provide a nice DSL for routing.
The trick will be to provide a way to define this both at the root level (similar to ApiRouter) and within a Resource definition (a la AttributeRouting).
I had to revert the overloads that accepted Giraffe's HttpHandler
signature as it always resulted in the builder selecting the default route rather than correctly matching. I was unable to determine why. However, manually applying a next
parameter works just fine.
The original commit adding these extensions was commit 4d3aab4.
Commit d02d122 reverted these changes and added an HttpHandler
module to adapt the signature.
Computation Expressions can define an Quote
member to provide back an Expr
that can be evaluated. This could be leveraged, along with Analyzers
, to restrict use of certain members to 0-1 uses. For example a resource { }
should only allow one get
, put
, post
, etc. use per definition.
@Krzysztof-Cieslak, are you using this approach in Saturn? Would you find this interesting, as well?
Facilitate hypermedia-driven transitions between Frank applications. It could be considered a meta-router driven by hypermedia.
Add view engine support to the DSL. Potentially use the Nina view engine abstraction, or do something similar with Nancy.
I also want to use this to tie into WebSharper, Wing Beats, and FsFormlets.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.