Skip to content
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

Document / provide samples for newbie use cases #368

Open
2 of 7 tasks
isaacabraham opened this issue Jan 5, 2016 · 10 comments
Open
2 of 7 tasks

Document / provide samples for newbie use cases #368

isaacabraham opened this issue Jan 5, 2016 · 10 comments

Comments

@isaacabraham
Copy link
Contributor

isaacabraham commented Jan 5, 2016

I'm loving Suave, but there are a number of common use cases people will go through the first time they try Suave and want to get a basic API or website going. The documentation for these areas is (IMHO) either: -

  • Too lightweight
  • Hard to find
  • Doesn't exist

I know that there's the Suave Music Store - which is a great example of using Suave - but most people will come to the main Suave website for help first, and it's here that I think getting-up-and-running scenarios / recipes should live. Here's a list of some of the questions / issues I had when starting with Suave. Some of them are already documented, but I'll put them all here anyway (and I'm happy to document the really simple ones myself): -

  • Multiple Routes: Great example here: https://suave.io/routing.html
  • Returning JSON data: Sort of. The guide here is not bad, but why call it "Restful services" - it's just about returning data as JSON, that's what the title should be. Also would be good to have a basic example of returning data using Json.NET. I wrote a simple function to do this (below) but spent a few minutes looking on the website and through the namespaces before I did it.
let toJson data = (JsonConvert.SerializeObject data |> OK) >=> setMimeType "application/json; charset=utf-8"
  • How do I serve up static files. The guide here doesn't talk anywhere about use of browseFile or similar - this (and variants) should be mentioned here with an example. This is (IMHO) a really common use case for people that e.g. want to serve up static content (HTML, js, css etc.) to host a SPA website and want to use F# for the back-end API.
  • 404 page. What's the idiomatic way of serving up a static HTTP 404 error page (or other page for e.g. HTTP 500)? How can I write a web part to catch an errors raised by another part to serve up the HTTP 500 (and ideally log the error)?
  • Ensuring webparts are always evaluated. By default a simple web part e.g. OK (sprintf "%O" DateTime.UtcNow) only gets evaluated initially. How do you force it to always get reevaluated? The answer is out there, but it's not easy to find.
  • Set up logging. The Logging section needs to be expanded and start with the most common question: how do I turn on logging of all requests? Even just to the console window to start with. Then, discuss how to write an alternative logger to the two that come with Suave e.g. TraceWriter or File System similar.
  • What's the easiest way to change the port that Suave listens on? I certainly didn't think to use the HttpBinding.mk method when I first needed to do this - I wrote it all out longhand using copy-and-update record syntax which looks terrible.

That's all I can think of at the moment. Hope it's useful!

@haf
Copy link
Contributor

haf commented Jan 5, 2016

Great input. As for serving files:

What would be great would be if you'd port these samples to the docs.

@isaacabraham
Copy link
Contributor Author

OK, I'll have a bash :-)

@matthid
Copy link
Contributor

matthid commented Jan 5, 2016

Because I started using suave as well and felt the same here some things that actually helped a lot:
https://github.com/SuaveIO/suave/tree/master/examples
IN particular the example here: https://github.com/SuaveIO/suave/blob/master/examples/Example/Program.fs
Because you can see a lot of stuff in action and different situations.

Stuff I had to figure out myself (and couldn't find good docs):

  • How to add custom states / helpers, for example

    • to track with Application Insights

    • you have something like http://example.com/resources/1231 and want to provide a helper function like pathScan which only continues when the resource exists AND at the same time resolves the object.
      How can this helper function made in a way to use it on http://example.com/resources/1231/doSomething or combine it with some nested object and compose it properly with the existing infrastructure.

      -> show an example using HttpContext.userState. This shows how flexible Suave is.

  • I agree on the logging, currently I'm currently using my own implementation in the userState map, because I couldn't figure out a good way to integrate it with System.Diagnostics and Application Insights.

  • Error handling... How is it done properly? When you construct a part of the response and detect an error how can you stop it with a proper response?

    -> Returning None/never stops the >=> pipeline and doesn't return the correct response.

    -> Returning a request continues the pipeline!

    Currently I'm using my own helpers with HttpContext.userState but there must be a better way, correct?

Whats the most suave way to do those things?

@isaacabraham
Copy link
Contributor Author

@matthid How are you hooking into AppInsights currently? Just using the raw SDK? As long as you can output logs to Trace, I believe that Azure should be able to pick that up and display / search through AI. I haven't been able to get the rich set of "raw" metrics through AI yet though even when hosting Suave through an Azure Website.

@isaacabraham
Copy link
Contributor Author

@haf ehm. What's the syntax for the markup in the docs? Doesn't look like regular markdown to me - how can I preview what it will look like.

@haf
Copy link
Contributor

haf commented Jan 5, 2016

@matthid I would use the trace information in HttpContext to associate log lines with the request. A new trace id is generated every time a request is accepted. I have been hoping for people to start to discover Logary, which can shove this information to e.g. Kibana and Grafana, or to help me create a zipkin target.

Something like

open Suave
open Logary

let logger = Logging.getCurrentLogger ()
let logging app =
  context <| fun ctx ->
    Logger.time logger (fun _ -> app ctx)

let main argv = 
  startWebServer defaultConfig (logging (App.entryPoint))

@haf
Copy link
Contributor

haf commented Jan 6, 2016

@isaacabraham It's markdown, but with some custom variant for code highlighting.

You can try it by running bundle exec rake docs. After that, start the server in the docs folder.

@haf haf added the docs label Jan 18, 2016
@Kurren-N
Copy link

Kurren-N commented Mar 5, 2016

An example of authenticating with an OAuth 2/OpenId Connect provider would also be helpful. Can suave use any existing libraries for this?

@haf haf added the you-take-it label Oct 3, 2016
@haf
Copy link
Contributor

haf commented Oct 3, 2016

Ticked the logging pieces as I've made logging the default in v2.

haf pushed a commit that referenced this issue May 31, 2017
Validate Server Key (#248) and docs (#368)
@rodgerbrennan
Copy link

rodgerbrennan commented Mar 30, 2018

"Ensuring webparts are always evaluated. By default a simple web part e.g. OK (sprintf "%O" DateTime.UtcNow) only gets evaluated initially. How do you force it to always get reevaluated? The answer is out there, but it's not easy to find."
I too was looking for the answer, and it was hard to find.

The answer is warbler

https://stackoverflow.com/questions/40561394/f-suave-warbler-function

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants