-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Should we drop Remote.withContext? #73
Comments
I would just remove |
|
I have some leverages with Giraffe HTTP handlers. |
Thinking more about it, I realized that it would actually be cleaner and a little bit more optimal to remove the let myRemoteHandler =
{
login = Remote.withContext <| fun http username -> async {
return! http.AsyncSignIn(username)
}
getUsername = Remote.authorize <| fun http () -> async {
return http.User.Identity.Name
}
getAdminStuff = Remote.authorizeWith [AuthorizeAttribute(Role = "admin")] <| fun http () -> async {
return "super secret stuff"
}
} would become something like this: type MyRemoteHandler(ctx: IRemoteContext) =
inherit RemoteHandler<MyRemote>()
override this.Handler =
{
login = fun username -> async {
return! ctx.HttpContext.AsyncSignIn(username)
}
getUsername = ctx.Authorize <| fun () -> async {
return ctx.HttpContext.User.Identity.Name
}
getAdminStuff = ctx.AuthorizeWith [AuthorizeAttribute(Role = "admin")] <| fun () -> async {
return "super secret stuff"
}
} @kos59125 I think this use case can be fulfilled with an additional overload on let myRemoteHandler (ctx: IRemoteContext) =
{
// same as above
}
// ...
services.AddRemoting(myRemoteHandler) Would that work well with Giraffe? |
Maybe no, for my case. But I think I may adapt Giraffe handlers to DI style with some changes. Here's my current code, FYR: // Giraffe handler to Bolero world
let withGiraffeHandler (f:HttpContext -> 'req -> Async<'resp>) (handler:HttpHandler) =
fun ctx req -> async {
let h = handler earlyReturn
match! h ctx |> Async.AwaitTask with
| Some(ctx) when ctx.Response.HasStarted -> return invalidOp "Giraffe handler must not start response"
| Some(ctx) -> return! f ctx req
| None -> return Unchecked.defaultof<'resp> // the handler rejects user request, response body will be "null"
}
|> Remote.withContext
// Giraffe handler
let forbidden : HttpHandler =
setStatusCode StatusCodes.Status403Forbidden
>=> handleContext (fun _ -> skipPipeline)
let checkroot : HttpHandler = fun next ctx -> task {
match ctx.TryUsername() with
| Some("root") -> return! next ctx
| _ -> return! forbidden next ctx
}
// Bolero handler
member __.Handler = {
DoSomething =
checkroot
|> Remote.withGiraffeHandler (fun ctx req -> async {
// do something for user "root"
})
} |
I see a |
Yes, __.Handler is a member of RemoteHandler. For Giraffe's handlers, HttpContext appears in function argument. I just feel weird HttpContext is also given from out of the function. With Remote.withContext, both Giraffe and Bolero works in function world. |
With my proposal you would pass the IRemoteContext to |
I understand. But, unfortunately, it fails with NullReferenceException. // ConfigureServices
services
.AddHttpContextAccessor()
.AddRemoting<MyRemoteHandler>()
// fix withGiraffeHandler from my code above
let withGiraffeHandler (ctx:HttpContext) f handler =
fun req -> async { (* use ctx here *) }
// RemoteHandler
type MyRemoteHandler(http:IHttpContextAccessor) =
interface RemoteHandler<> with
member __.Handler = {
DoSomething =
checkroot // giraffe handler
|> withGiraffeHandler http.HttpContext (fun req -> async { ... })
} maybe because of this? |
Yes, you need to pass |
Thanks, I get it. It works perfectly and I understand I don't need change my Giraffe handlers. |
As @OnurGumus remarked here, we technically don't need
Remote.withContext
. It is possible to access the current request's in an async-safe way by injectingIHttpContextAccessor
.Code like this:
can be written like this:
So, should we remove
Remote.withContext
, and also maybe haveRemote.authorize
not passHttpContext
anymore?Arguments for keeping
Remote.withContext
:Remote.authorize
.Arguments for removing
Remote.withContext
:The text was updated successfully, but these errors were encountered: