GithubHelp home page GithubHelp logo

Comments (12)

dustinmoris avatar dustinmoris commented on July 23, 2024 3

I've migrated the entire PR into its own repository a while ago. It builds and I think it should work now, but might need a bit of testing with the latest version of Giraffe. I also have to set up the build pipeline for a NuGet package, which I should be able to get done over the next few days:

https://github.com/giraffe-fsharp/Giraffe.Swagger

If you have any questions or want to help then please open a new issue there.

from giraffe.

piaste avatar piaste commented on July 23, 2024 2

@dustinmoris, the big argument for automatic doc generation is safety and maintenance. It's no different from how Project Scaffold autogenerates an API reference page, as countless other documentation tools have done since Javadoc.

Would you want to write those by hand, having to constantly keep them up-to-date and potentially committing all kinds of human errors? If not, why is it different when it's an HTTP request rather than a library function call?

Also if I'd be working in a team which has to document an API with Swagger, then I wouldn't want to tie the Swagger generation to .NET code, because now only .NET developers can generate or update the documentation. On the other hand a .yml file is supposed to be human friendly for reading, understanding and editing, so in theory I could pass on the documentation to a stakeholder, QA person, product owner, or anyone else on a team who could test the API according to the .yml file and potentially correct any issues in the .yml file themselves. This is sort of one of the big benefits of Swagger and by moving the doc generation to .NET code this whole purpose gets lost, right?

Eh, not really. First, Swagger/OpenAPI is meant at least as much for machines as for humans - the documentation it generates is a reference, not a presentation. Sure, you can write it by hand in YAML, and read the YAML with human eyes, but that's a plan B compared to using swagger-codegen and similar tools (although an important plan B: it mitigates the WSDL scenario where it's awesome if your IDE automagically integrates it and horrible if it doesn't).

If you have the luxury of tasking a non-developer with writing proper documentation, then Swagger isn't likely to be their tool of choice, because (a) it's very restricted (nothing but plaintext or at best Markdown descriptions, forget about pictures and diagrams), and (b) a basic reference layout makes for poor learning. It's no coincidence that the spec includes an external-docs URL field for most objects.

If you don't have the luxury of writing proper documentation - that's where Swagger and similar tools come in. Just comment your public API calls and your objects' public properties and you'll have at least a usable reference, if nothing else. Or even if you don't comment it at all, the tooling will still create a reference of your method signatures.


In any case, putting my money where my mouth is: I've been working on an OpenAPI (Swagger 3.0) library for Suave, still using a wrapper-based approach but with what I hope is going to be a much less clunky UX than the existing Suave.Swagger module (basically I'm providing most of the same combinators as Suave, choose, GET, Ok/NotFound etc., except these combinators are records containing both a WebPart and a DocPart, the latter of which combine to create the spec).

Once I publish it, it should be quite straightforward to port it from WebPart to HttpHandler, since the structure is so similar. That said, if Giraffe could support APIExplorer and then lean onto Swashbuckle's more well-established tooling and user base, that would be a much more robust solution (and more in line, I think, with Giraffe's philosophy of 'let's use the big boys' stuff').

from giraffe.

JonCanning avatar JonCanning commented on July 23, 2024 2

https://github.com/Microsoft/OpenAPI.NET

from giraffe.

ElijahReva avatar ElijahReva commented on July 23, 2024 2

Hi, could anyone review PR #218, please? This nasty feature ready, I hope, to satisfy all its possible consumers!

Ci is failed due to 'dotnet-xunit' not found, perhaps you forget to add NuGet package .

from giraffe.

slang25 avatar slang25 commented on July 23, 2024

I was thinking about this a few months ago, I found it an interesting thought experiment.

Giraffe doesn't directly use MVC (well it does for the Razor engine), it uses ASP.NET Core directly, so Swashbuckle/ApiExplorer isn't something we get for free, so I think the question is how do we expose a swagger doc for a Giraffe composed app in an easy and idiomatic way.

In terms of web frameworks, approaches vary vastly, for example:

ASP.NET MVC - This is convention based, and you can deviate from the conventions, at runtime you can reflect on the current application. You can enumerate the routes, then reflect on the controllers. Where the types are exposed (cause IHttpActionResult is not generic) you can influence the swagger docs with attributes.

Freya - You compose an application that results in a decision tree, at runtime this is reduced, optimized and executed, which is pretty cool. It also means that this tree can be walked through and swagger docs can be built from the collected information provided by this tree, very cool.

Suave & Giraffe - These frameworks let you build you app as just a function, with functional composition. This makes things simple, and fast. That said, the above frameworks are fast too, but they require hard work and complexity inside the framework code to achieve this, Giraffa gets it for free =)
Because it is just a function, you can only invoke it, so you could pass in a dummy request through it and capture the output, but you don't know how to vary the request to explore the whole app and reverse engineer it. What you would need is to be able to pass through a collector, each HttpHandler (or Suaves WebPart) would contribute to it, and the combinators would know to always continue and pass it through.

@piaste I hadn't considered the approach you had highlighted above where you provide a separate dsl that mirrors the original, and under the hood builds you the "plan" dsl version, and builds the swagger. And to do it by utilizing ApiDescription is also an interested suggestion, I'd be interested in just hacking about and seeing if this was possible, although don't realistically have the time. Would love to hear other thoughts on this.

from giraffe.

gerardtoconnor avatar gerardtoconnor commented on July 23, 2024

Gentlemen, this may be something we can build in as default on new routing system as the base function becomes a radix tree with route endpoint handlers such that all routes should be easily iterated through so that each route can be tested/mapped. May mean two versions of the router (or base function has a parameter to expose swagger or not). We can do a bit of hacking once router released.

One thing to note is that api parse variables are largely printf format of %s %i etc, such that they are not named which makes the api less expressive. We would need to either change the parser to use named variables or add annotations/metadata.

Adding named variables is not as easy as it sounds without adding more work for the dev (StringFormat<'T> generates type sig from string), I had been prototyping generative type-provider to allow the parsing & creation of types based on a named parameter api string but generative type providers do not work on .net core yet (and erased are not performant enough for high throughput routing), so it forces the user to define named property types for each and every route parse which is a pain when StringFormat/printf can magically create the type for you.

from giraffe.

dustinmoris avatar dustinmoris commented on July 23, 2024

I wonder how good these auto generation tools really are, because how do these tools document error responses which often come from a central module or error handler or how do these tools document endpoints across different middleware?

from giraffe.

gerardtoconnor avatar gerardtoconnor commented on July 23, 2024

@dustinmoris I think for the basic documentation case (Swagger has extensive functionality), swagger would just list the api endpoint URLs and in a method similar to postman/fiddler, you can test urls with variables etc on a live server so that you can see the response (or error response). On diff middleware...need to explicitly do mapping? Would question effort alright. Looking further into it more problems stack up

  • As mentioned already, currently parse symbols are not named
  • Much of the value is in comments/description of api so we would need annotations on all routes ... but annotations are not allowed on specific instances of a common class so needs to be a function param.
  • handling of Authentication, Verbs etc all needed but again class/method annotations not viable

That being said, it is probably appealing to some so as a separate nuget package it may be nice provided it does not pollute the base Giraffe library.

The likely solution would be different handler namespace that replaced certain handlers with wrapped/overloaded versions that interacted with an internal state object (held in HttpContext Items Dictionary) such that it could iterate it on build/startup and generate the swagger spec json file that could then be viewed through the online swagger viewer.

There would need to be some pretty good interest to go through all this design & coding IMHO ... if you look at the Suave implementation example, yes it works but I would find it a nightmare to program, adding so much clutter and complexity vs standard api of an app.

from giraffe.

dustinmoris avatar dustinmoris commented on July 23, 2024

Hi,

This issue has been a little bit stale and I do not only wonder how realisitc it is to get this done, but also if it is really any useful.

I still struggle to understand the actual value of this, because I don't think there's any less work for a developer after all. Instead of having to document an API in yml the user now has to document the API with .NET attributes (or some other F# construct).

So basically it is still up to the developer to
a) document the API manually
b) not forget to update attributes or something else when the API changes

Seems to me that this is a lot of work for merely shifting documentation from YML to .NET code, without a clear benefit. Now the one thing which I really struggle to understand is: Swagger is supposed to be a user friendly and easy way of documenting APIs. Unlike .NET or F# it has been specifically designed for that one purpose only, so how can .NET attributes be superior in documenting an API than a language/tech which has been specifically designed for it? If Swagger is still too complex, then should the people who want to document APIs not rather look for improvements of Swagger instead?

Also if I'd be working in a team which has to document an API with Swagger, then I wouldn't want to tie the Swagger generation to .NET code, because now only .NET developers can generate or update the documentation. On the other hand a .yml file is supposed to be human friendly for reading, understanding and editing, so in theory I could pass on the documentation to a stakeholder, QA person, product owner, or anyone else on a team who could test the API according to the .yml file and potentially correct any issues in the .yml file themselves. This is sort of one of the big benefits of Swagger and by moving the doc generation to .NET code this whole purpose gets lost, right?

from giraffe.

xperiandri avatar xperiandri commented on July 23, 2024

Instead of having to document an API in yml the user now has to document the API with .NET attributes (or some other F# construct).

With ASP.NET Core API Explorer this happens almost automatically.
You don't use any attributes additional to ASP.NET Core except for sample view models.
So why not just plug Giraffe into API Explorer?

For me I don't understand a benefit of having a single route composition root like Giraffe obligates to do. I would better decorate functions with attributes and never mind of fixing routes decision tree.

from giraffe.

dburriss avatar dburriss commented on July 23, 2024

We use Swagger extensively at work for things like:

  • PO checking input/output on a new feature
  • Documentation of the APIs
  • Auto-generation of clients for the APIs for various programming languages

It definitely beats maintaining a yaml file (which I have done in the past) for both creation and staying up to date.
Not having this would unfortunately make Giraffe a non-starter in an environment where is is expected.

A few ideas have been mentioned, does anybody have a good feel for how to move forward on this?

from giraffe.

rflechner avatar rflechner commented on July 23, 2024

Hi,

I did not find solution to populate ApiDescription.

But I explored another solution in this PR #218

Regards,

@rflechner

from giraffe.

Related Issues (20)

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.