Git Product home page Git Product logo

falco's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

falco's Issues

How to use Falco directly with an existing C# MVC application via IEndpointRouteBuilder and the RazorViewEngine?

I'm currently using OrchardCore to build a SaaS platform, and it relies exclusively on C# MVC using .NET Core. It uses a system that pulls Startup classes from any referenced class libraries ("modules") and merges together their content. Specifically, each Startup mounts endpoints using an IEndpointRouteBuilder with calls to MapAreaControllerRoute which all have to specify exact details like the controller, the action, the area, the pattern, etc.

I've been trying to see if I can use F# from start to finish in creating a basic module, but I have to fully emulate the experience of using MVC. That is...

  • they compile virtual razor template paths using "areas" scoped to each specific module's name.
  • they use physical paths during development and embedded views with virtual paths during production.
  • the controller/action/area metadata has to be associated with each route.
  • the controller actions all return Task<IActionResult>, and if it's a View, then it gets embedded within a larger View powered by a configurable Theme system in OrchardCore.

I can't really use Giraffe since it just writes content to the response directly (which would disregard the Theme system). It also only supports Microsoft's endpoint stuff in it's most recent alpha builds, so meh. Falco, on the other hand, is built entirely with seamless integration of AspNetCore in mind, so I'm hoping you have suggestions on how I might approach this.

I figure I could write some sort of HttpHandler that registers the endpoints along with the appropriate metadata. Then, it's just a matter of figuring out how to take an HTML string and directly inject it into an inline View that is picked up by Razor and used in OC's theme system.

Retrieve JsonSerializerOptions from Services

I've been thinking here, could we add support for the library consumer to register his own JsonSerializerOptions from the Services collection?

Say he has his own settings to apply for JSON parsing or has another library to be used in place. We could look for a JsonSerializerOptions from the services and use that instead of Constants.defaultJsonOptions if it exists.

Errors in Tutorial?

Hello,

I am following the steps here: https://www.falcoframework.com/#getting-started

I run the following steps:

  1. dotnet new -i Falco.Template::3.0.0
  2. dotnet new falco -o HelloWorldApp

I get this error message

`PS C:\Users\grampal\Documents\Programming\FSharp\FalcoStuff> dotnet new falco -o HelloWorldApp
Couldn't find an installed template that matches the input, searching online for one that does...
Matches from template source: NuGet

Template name "Falco" (falco) from author "Pim Brouwers, Daniel Tuna and contributors" in pack Falco.Template
To use this template, run the following command and try again:
dotnet new -i Falco.Template::3.0.0`

I have tried VSCode and Visual Studio as well.

Please help.

Falco 4 handler not responding correctly.

When doing handler composition, there seems to be a regression in Falco 4 which causes the handler to not respond correctly (200 OK with empty body). This however, works as expected in Falco 3

You can view a repro here: https://github.com/sheridanchris/FalcoRepro

You'll notice in the repro there's a do! Task.Delay(...) in both versions. If you remove this from the Falco 4.0 version it seems to work fine (if that gives you any hints).

html static webpages

Hi Pim. Thanks for putting time on Falco. I'm new to both F# and Falco and I'm learning through creating stuff πŸ™‚ . One question I have is how do I render .html static files and edit the attributes and elements/nodes in Falco or something like template rendering.

`UseConfiguration()` missing from webApp builder

Currently there is no way to activate configuration files (appsettings.json)

A typical webhost builder:

WebHostBuilder()
    .UseKestrel()            
    .UseContentRoot(Directory.GetCurrentDirectory())
    .Configure(configureApp)            
    .ConfigureServices(configureServices)
    .ConfigureLogging(configureLogging)
    .UseConfiguration(config) // this is missing
    .Build()
    .Run()

Request: Update Tags/Releases feature for repository

The latest version of the library is 4.0.3 on NuGet, but the latest tag/release on GitHub is 3.1

screenshot of releases page

Since there's no CHANGELOG.md in the repository, it can be confusing trying to identify

  1. What has changed between versions
  2. What the latest official released version from the repository code main/master branch is

The Releases page for the repository is commonly used to help developers understand when new releases and what the changes were for each version. It can be really helpful for new developers trying to orient themselves in the repository/versioning history.

Could the Releases/Tags be updated for Falco to reflect that 4.0.3 is the latest and what changes are in it since 3.1 (even if you just summarize the changes).

Thanks!

Comparison with Giraffe/Suave

Hi, this project looks great, but what i'd really love to see would be comparison with existing & popular web frameworks like Giraffe and Suave.
Also, it would be nice to include some benchmarks - one of core feature of .net platform is it's speed.

Thanks for your work & keep it up!

Question: How to do routing on a multilingual site?

Hi Pim,

After Ben Gobeil's great introduction to Falco (https://www.youtube.com/watch?v=DTy5gIUWvpo), I decided to take a closer look at your repo.

I especially liked your blog example where you use markdown and YAML frontmatter for the content (https://github.com/pimbrouwers/Falco/tree/master/samples/Blog). This approach might be a good way to convert a tiny PHP site of mine (http://www.zp-tec.com) and use it a training ground to sharpen my F# skills.

OK, now to my question:

The new version of my site will be multilingual, so all URLs of the second language have to be prefixed the with country code like this: /<country_code>/path/to/slug/.

How do I do this with Falco? Do I need to add the prefix to every slug manually, or is there some concept of nested routing like in Saturn? Or any other way to deal with multilanguage URLs?

For example, Saturn has something like nested routes (https://saturnframework.org/explanations/routing.html), but Falco's route and all functions in Routing.fs don't seem to have this feature.

I also read Microsoft's article about endpoint routing you link to on your README page, but couldn't find a solution there either. That said, although I feel more and more comfortable programming in F#, I've never done anything with ASP.NET.

Have a good day!

Stefan

Webhost Builder computation expression

Proposing that a computation be created to simplify the process of creating the webhost.

webhost {
    logging (fun options-> ...

    services (fun services -> ...

    activateWhen isDevelopment (fun app -> ...

    activate (fun app -> ...
}

Endpoint routing not working with .net 6 preview 6 minial api swagger integration

I am trying falco with swagger. Because recently I read some post that swaggert now support .net 6 endpoint routing start from preview 6. But unfortuatly it is not working with falco endpoint.

Below is the demo code:

open System
open System.Threading.Tasks
open Microsoft.AspNetCore.Http
open Microsoft.AspNetCore.Builder
open Microsoft.Extensions.DependencyInjection
open Falco
open Falco.Routing


let builder = WebApplication.CreateBuilder()

builder.Services.AddEndpointsApiExplorer()
builder.Services.AddHttpContextAccessor() |> ignore
builder.Services.AddSwaggerGen() |> ignore

let application = builder.Build()

application.UseSwagger() |> ignore


application.UseFalcoEndpoints [
    get "/" (Response.ofPlainText "Hello World")
]

// not working
// falco will call toRequestDelegate to convert handler into RequestDelegate which will erase the return type wrapped in Task
// if we can find a way to change to Func<_, _> style with more type info then we can integrate with swagger
application.MapGet("/hello1", RequestDelegate(fun (ctx: HttpContext) -> Task.FromResult $"Hi {ctx.Request.Path}" :> Task)) |> ignore

// working
application.MapGet("/hello2", Func<_, _>(fun (ctx: HttpContext) -> $"Hi {ctx.Request.Path}")) |> ignore

application.UseSwaggerUI() |> ignore

application.Run()

Question: why another F# view engine?

Out of curiosity, why does this project contain another F# view engine? In other words, how does this one differ from the ones in Fable, Giraffe, etc.?

Question: XSS vs CSRF

Hello, what follows is just a nitpick from browsing the code. Feel free to disregard and close if it's not relevant.

I was having a look at the library and noticed that the namespace handling AntiForgeryTokens was named "XSS".
Most of the time I see such a module named something to do with CSRF rather than XSS, since the responsibility of the AntiForgeryTokens is to prevent Cross-Site Requests. While Cross-Site Requests could be triggered by an XSS attack triggering an ajax form request, the scope of XSS is much more broad in it's scope (reflected vs stored vs DOM), and the defenses have more to do with output sanitization/encoding ("safe sinks") rather than input origin verification.

Broken Link & Spelling for "function composition"

On this line,

Falco/README.md

Line 237 in f2c5753

Response modifiers can be thought of as the in-and-out modification of the `HttpResponse`. A preamble to writing and returning. Since these functions receive the `Httpcontext` as input and return it as the only output, they can take advantage of [function compoistion](22).

The link is broken when clicking.

function composition is spelled function compoistion

Combine multiple class attributes

Hi, would it be possible to combine multiple class attributes the way Elm does it?

I'm using tailwindcss and usually define some helper functions for commonly used components e.g.:

let button (attrs : list<XmlAttribute>) =
    Elem.button (
        Attr.class' "border rounded px-4 py-2 bg-blue-500 text-white"
        :: attrs
    )

let wideButton =
    button [ Attr.class' "w-64" ]

Unfortunately this doesn't work at the moment because only the first class attribute will be used by the browser. Do you think this would be a useful feature?

Also thank you for creating Falco!

Unable to serialize DtResponse object.

I have a very strange bug. I am unable to serialize an object. I am using https://github.com/DataTables/Editor-NET. I am able to wire up all the request info properly and I have even been able to serialize single fields of the DtResponse object, but not the object itself. There's no errors and I'm kind of unsure as to what's happening. I tried looking over the code for projects but I don't really see anything that would cause the object to not serialize.

One thing I did notice in my research is that the ".Flush()" method is overridden on MemoryStream so calling it in the serialize function doesn't do anything according to: https://docs.microsoft.com/en-us/dotnet/api/system.io.memorystream.flush?view=net-6.0.

How to debug it on Visual Studio?

I'm new to F#. I've setup VS code with Ionide, it works well.
But I also would like to try Visual Studio, and can't connect it with Falco for debugging (server doesn't start), could you help please?

Add CORS support to HostBuilder

I'm working with Falco and a SPA that needs to call different services.
Thus I need CORS enabled on each of them.

As I did not find CORS support in Falco yet and I think it's useful to have I propose extending the webHost CE accordingly.

I'll work on a PR for the feature.

Extract Falco endpoints loop

Hello,

I think it can be useful to extract this code

for endpoint in endpoints do
for (verb, handler) in endpoint.Handlers do
let requestDelegate = HttpHandler.toRequestDelegate handler
match verb with
| GET -> r.MapGet(endpoint.Pattern, requestDelegate)
| HEAD -> r.MapMethods(endpoint.Pattern, [ HttpMethods.Head ], requestDelegate)
| POST -> r.MapPost(endpoint.Pattern, requestDelegate)
| PUT -> r.MapPut(endpoint.Pattern, requestDelegate)
| PATCH -> r.MapMethods(endpoint.Pattern, [ HttpMethods.Patch ], requestDelegate)
| DELETE -> r.MapDelete(endpoint.Pattern, requestDelegate)
| OPTIONS -> r.MapMethods(endpoint.Pattern, [ HttpMethods.Options ], requestDelegate)
| TRACE -> r.MapMethods(endpoint.Pattern, [ HttpMethods.Trace ], requestDelegate)
| ANY -> r.Map(endpoint.Pattern, requestDelegate)

in another extension method to do it manually and be more compatible with existing C# endpoint extension like this :

app
  .UseBlazorFrameworkFiles()
  .UseRouting()
  .UseEndpoints(fun e ->
                e.UseFalcoEndpoints(endpoints)   // <- new extension 
                e.UseHotReload() |> ignore
                e.MapBlazorHub() |> ignore
                e.MapFallbackToPage("/_Host") |> ignore)

If you ok I can also do this in a PR πŸ˜‰

Feature requests or breaking changes for Falco v3.x.x

With .NET 5.0 finally here, it seems like a good time to begin exploring v3.x.x which will support both the netcoreapp3.1 and net5.0 build targets.

In saying that, this is a great opporunity to include any new features and/or breaking changes to the API. Included so far:

  • Removal of the [<AutoOpen>] attribute in the routing module to prevent polluting the global scope
  • Addition of "multi-method" endpoints
  • Validation module

So, if you're a user of Falco and you have some ideas, I want to hear from you!

Docs Website

Would you be interested in some static website documentation 😁?
something like this it's basically a Fornax "blog"

my UI design skills are atrocious as you can see but I can help you setting it up and pushing content if you like the idea

falcoframework.com is down

Not sure if this is the right place for this, but falcoframework.com is down. Not a DNS issue because the 404 message is from GH.

image

WebHost Builder - do we need/want this?

Tabling this discussion since there's enough of us now using, or at least watching this project from a distance.

I originally wrote the comp expr for the web host to avoid the need for so much boiler plate code around creating a new web host. I'm beginning to feel as though I'm not a fan of hiding away the complexity, and the additional API that now needs to be maintained.

So what do you think?

Any template engine integration?

Hey Pim

are there any plans for integrating with a template engine?
A lot of my frontend work is just copy paste from various sites and having support for html syntax would be great.

Sample Project Ideas

Opening the floor to ideas for sample projects.

We currently have:

  • Hello world
  • Markdown blog

Some of my ideas:

  • Todo MVC (kind of boring)
  • A restaurant booking system (a la @ploeh)
  • A public notepad (i.e. jsfiddle for plain-text)

Json Serialization

Hey, I just discovered Falco and it looks pretty neat! I'll try to give it a run on the following days

I just have a question about JSON serialization/deserialization I saw that you are using the System.Text.Json API's

I believe I tried those previously in another project but ran into exceptions once I tried to deserialize option types as well as Discriminated Unions, with that in mind

Is it safe to just deserialize json?

if not, you might want to consider taking a look at
https://github.com/Tarmil/FSharp.SystemTextJson
which uses the same API's but with some F# sugar for those mentioned types

Model Binder value API is not case-insensitive

Consider:

[<Fact>]
let ``StringCollectionReader value lookups are case-insensitive`` () =
    let values = 
        [ 
            "FString", [|"John Doe"; "Jane Doe"|] |> StringValues                
        ]
        |> Map.ofList
        |> fun m -> Dictionary(m)

    let scr = StringCollectionReader(values)

    // single values
    scr.TryGet "FSTRING"   |> Option.iter (should equal "John Doe")
    scr.TryGet "FString"   |> Option.iter (should equal "John Doe")
    scr.TryGet "fstriNG"   |> Option.iter (should equal "John Doe")
    scr?FSTRING.AsString() |> should equal "John Doe"
    scr?FString.AsString() |> should equal "John Doe"
    scr?fstrINg.AsString() |> should equal "John Doe"

    // arrays
    scr.TryArrayString "FSTRING" |> Option.iter (should equal [|"John Doe";"Jane Doe"|])
    scr.TryArrayString "fString" |> Option.iter (should equal [|"John Doe";"Jane Doe"|])
    scr.TryArrayString "fstriNG" |> Option.iter (should equal [|"John Doe";"Jane Doe"|])
    scr?FSTRING.AsArrayString()  |> should equal [|"John Doe";"Jane Doe"|]
    scr?fString.AsArrayString()  |> should equal [|"John Doe";"Jane Doe"|]
    scr?fstriNG.AsArrayString()  |> should equal [|"John Doe";"Jane Doe"|]

Docs: minor error in Falco.Markup docs

I think there's an error in the code sample under the heading "Combining views to create complex output". It currently reads:

// Template
let master (title : string) (content : XmlNode list) =
    Elem.html [ Attr.lang "en" ] [
        Elem.head [] [
            Elem.title [] [ Text.raw "Sample App" ]
        ]
        Elem.body [] content
    ]

That hard-codes the page title to "Sample App", whereas if I'm right(?) it should use the title parameter. Corrected code:

// Template
let master (title : string) (content : XmlNode list) =
    Elem.html [ Attr.lang "en" ] [
        Elem.head [] [
            Elem.title [] [ Text.raw title ]
        ]
        Elem.body [] content
    ]

Happy to submit a PR though realise it's a trivial change so might be overkill. Thanks.

Docs: re-direct examples out of date

Falco and dotnet newbie here, so apologies if this is mistaken.

The redirect docs suggest there are two functions, one each for perm and temp redirects. However, the examples don't compile using Falco 3.1.14 & Fsharp.Core 7.0.0. I think the examples should be as follows:

let oldUrlHandler : HttpHandler =
    Response.redirect "/new-url" true
   
let redirectUrlHandler : HttpHandler =
    Response.redirect "/new-url" false

Hope that helps. As an aside, I'm really enjoying the Falco "on ramp" experience. Thanks for all your hard work.

Docs: minor error with Routing

Hello, I've noticed a small issue here:
https://github.com/pimbrouwers/Falco/blob/master/doc/routing.md

open Falco
open Falco.Routing
open Falco.HostBuilder

webHost [||] {
    endpoints [
        get "/hello/{name:alpha}" (fun ctx ->
            let route = Request.getRoute ctx
            let name = route.GetString "name" "" // <- This Doesn't compile for me
            let message = sprintf "Hello %s" name
            Response.ofPlainText message ctx)
    ]
}

However this is completely fine:

webHost [||] {
    endpoints [
        get "/hello/{name:alpha}" (fun ctx ->
            let route = Request.getRoute ctx
            let name = route.GetString ("name", "") // Change to tupled parameters made here
            let message = sprintf "Hello %s" name
            Response.ofPlainText message ctx)
    ]
}

The route binding example from here: https://www.falcoframework.com/docs/request.html#route-binding
Is completely fine and uses a simplified version, like this:

open Falco

// Assuming a route pattern of /{Name}
let manualRouteHandler : HttpHandler = fun ctx ->
    let r = Request.getRoute ctx
    let name = r.GetString "Name"
    Response.ofPlainText name ctx

let mapRouteHandler : HttpHandler =
    Request.mapRoute (fun r ->
        r.GetString "Name")
        Response.ofPlainText

Which would translate our first example to something like this:

webHost [||] {
    endpoints [
        get "/hello/{name:alpha}" (fun ctx ->
            let route = Request.getRoute ctx
            let name = route.GetString "name"
            let message = sprintf "Hello %s" name
            Response.ofPlainText message ctx)
    ]
}

That would be one of my suggestion the other is using a working tupled example in a more descriptive way:

webHost [||] {
    endpoints [
        get "/hello/{name:alpha}" (fun ctx ->
            let route = Request.getRoute ctx
            let name = route.GetString ("name", "FalcoEnthusiast") // Could be "defaultValue", "fallbackValue"
            let message = sprintf "Hello %s" name
            Response.ofPlainText message ctx)
    ]
}

But my question is will it ever be an empty string here? Maybe the fallback value is never needed in this example?

I would be very happy to make a PR for that, but it is also a trivial change so might be an overkill.
Have a great New Year Pim and everyone! :)

Use different port?

I was wondering how you configure the host to use a different port? It seems like it would be a useful feature in the CE for webHost.

Best practice for http2

Good day, I'd like to create a web service, which should use http2 protocol. How to do it? 1) put Nginx with http2 at front of Falco, or 2) setup Kestrel with http2 support? If 2 is preferable, how to setup Kestrel from Falco? Thanks in advance.

Question: Elem.button - onClick?

Hello,

how do I assign function to button's onClick in Falco?

I am attempting something like: let button = Elem.button [ Attr.onClick (fun _ -> xxxx) ] [ ]

but it does not exist. I was looking into Falco source code for something like onClick but I have not found anything.

[Question] Response.debugRequest is not defined

Hi all, I'm discovering Falco and going through the samples.

I tried the following:

[<EntryPoint>]
let main args =   
    webHost args {
        use_if    FalcoExtensions.IsDevelopment DeveloperExceptionPageExtensions.UseDeveloperExceptionPage
        use_ifnot FalcoExtensions.IsDevelopment (FalcoExtensions.UseFalcoExceptionHandler exceptionHandler)
        
        endpoints [            
            get "/" (Response.ofPlainText "Hello world")
            get "/hello/{name:alpha}" (Request.mapRoute (fun route -> route.GetString "name" "") Response.ofPlainText)
            get "/form" (Response.ofHtml form)
            post "/form" (Response.debugRequest)
        ]
    }

I'm getting the following error when I compile:

  Program.fs(34, 36): [FS0039] The value, constructor, namespace or type 'debugRequest' is not defined.

I'm running the version:

  <ItemGroup>
    <PackageReference Include="Falco" Version="3.1.*" />
  </ItemGroup>

i can clearly find the function debugRequest on the source code on the latest release and does not seem to find any commit that removed it... weird...

I'm running on Mac OS M1. Can this be related?

Thank for any help

Add dapper

Hello guys.
I'm having trouble adding Dapper to Falco.
Do you have any code example?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.