OpenAPI & .NET: You're Doing It Wrong - Mark Rendle - NDC Oslo 2023

แชร์
ฝัง
  • เผยแพร่เมื่อ 12 ก.ค. 2023
  • .NET developers have two options when it comes to OpenAPI or Swagger: Swashbuckle and NSwag. Just decorate your controllers or minimal API endpoints with a bunch of attributes and a NuGet package will generate the swagger.json file for you, right?
    No. Wrong. That's not how this is supposed to work.
    In this talk, Mark will try to convince you that the correct way to implement OpenAPI is to write and maintain that file manually. Probably as YAML instead of JSON. That way it's included in your version control history, you can use it to generate Markdown docs in a GitHub action, and people don't need to run your app to get a copy of the file.
    Mark is working on some new NuGet packages that will provide some pretty neat functionality for static OpenAPI files, including serving SwaggerUI and beautiful documentation with code samples, generating application and test stubs, validating your implementation against the spec, and more.
    Check out our new channel:
    NDC Clips:
    ‪@ndcclips‬
    Check out more of our featured speakers and talks at
    ndcconferences.com/
    ndcoslo.com/
  • วิทยาศาสตร์และเทคโนโลยี

ความคิดเห็น • 28

  • @RoamingAdhocrat
    @RoamingAdhocrat 11 หลายเดือนก่อน +10

    watching to work out if the TH-cam title card is intentionally Like That

  • @orterves
    @orterves 11 หลายเดือนก่อน +12

    "REST APIS was a stupid idea and we're not doing it" - instant like

  • @RFalhar
    @RFalhar 11 หลายเดือนก่อน +8

    I have some issues with this.
    First is that the API-first approach doesn't seem to work, at least for me. Being able to do API-first means that you have detailed understanding of requirements and how will client-server communication work. That implies a detailed up-front specification and design. And this doesn't fit how I and most others approach work: Gradual and incremental. I have experience from big project where we have an API catalog repository with all the specifications. Then there is custom tooling to push specifications to specific repositories of services and clients, with those using OpenAPI generators to generate client calls and server stubs (in Kotlin). And the workflow is always the same: Make changes to local service, make sure the API definition works and is usable, and only then manually copy the changes in specification into the catalog. It was even more pronounced on new different project. There too was initial attempt at defining API first so that client and server can be made in parallel. It immediatelly broke down, as we realized we didn't understand the requirements and had little understanding of the process. So we had to just implement the API and use the one generated by .NET.
    Second issue is that tooling for generating .NET code from OpenAPI is just not good. The one for OpenAPI kind of works, but from playing around with it, I found there are some missing features that make it not usable for most scenarios. It requires either Java installed or run in Docker. It isn't natively integrated into MSBuild. The generated classes are all ugly DTO classes and not clean looking records. It isn't posible to ignore specific components, that you have already exist in codebase and shouldn't be generated. It is using Newtonsoft Json, and even if there is toggle to turn it off, it isn't cleanly serialization-agnostic.
    I do wonder why Mark hasn't mentioned this. I do know he is working on his own codegen, but is keeping it secret for now.

    • @Marfig
      @Marfig 10 หลายเดือนก่อน +1

      I've had similar problems with design-first approaches to API development, even before OpenAPI was a thing. The reality of the development process is that we can indeed easily start with a design-first approach, but once development starts in earnest, it's just not possible to keep it going and we invariably move to code-first. And at that point in time, we are in a world of hurt making sure we keep the documentation in sync with our code. This happens to us because the design cycle simply can't keep up with the development cycle. As you say, often we find ourselves changing the design mid-development as the feature matures and the acceptance criteria stops being constantly updated mid sprint. What OpenAPI lacks is the proper tooling to allow us to work code-first on an existing documentation.
      So no. We aren't doing it wrong. OpenAPI just doesn't give us what we need.

  • @jimbob1xghtnm
    @jimbob1xghtnm 11 หลายเดือนก่อน +5

    I have also concluded that using NSwag/Swagger is a dead end. On a current project, I spent so much time implementing workarounds to produce the correct OpenAPI document that I would have been better off if I had just created it by hand. Moreover, my API code base is now littered with code that has nothing to do with the API functionality but is there only to support creating a correct OpenAPI document. Sadly, I am a solo founder and don't have time to waste ripping it out, but once I have time to spare, all that code is going in the dustbin. I won't make this mistake again.

    • @RFalhar
      @RFalhar 11 หลายเดือนก่อน +1

      Can you tell what was motivation behind crafting specific OpenAPI document? I think it always generate a correct document. What did you think was "incorrect" about defaultly generated documents?

    • @jimbob1xghtnm
      @jimbob1xghtnm 11 หลายเดือนก่อน +5

      @@RFalhar I had some complex serialization/deserialization rules where, in some cases, you can pass either a string value for some JSON properties, or you can pass one of multiple complex objects. My custom serializers handle the deserialization correctly, but I could not get these correctly represented in OpenAPI document. Out of the box, Swashbuckle did not know what to do with this, so I had to add many `options.MapType` calls in my call to `AddSwaggerGen()` to define these schemas. Also, I used the SmartEnums class and Swashbuckle did not know how to represent these correctly.
      BTW, I spoke wrong in my first message - I have actually since removed Swashbuckle from my project after migrating to FastEndpoints.

  • @bangonkali
    @bangonkali 11 หลายเดือนก่อน +4

    I'm guilty about using nswag but we have a very customized nswag startup (incantations) wherein we actually have very customized redoc and swagger outputs. We output both and it depends on the API consumer which they like they can have access to both.
    However the reasoning has been mostly between making sure correctness of the doc generated vs the implementation.
    Design Discussions on datastrucure and API happens on scratch markdown files or in specific github/gitlab issues comment chain /description until finalized and implemented.
    Looking at this presentation I can't help but reminisce my EE days. Had there been solutions similar to DESIGN RULE Check (DRC) similar to the semiconductor and electronic design automation (eda) tools as mentioned near the end of the presentation it would have been particularly great to start with this approach.
    There have been so many times when documentation have been left unattended and people no longer know which is correct, the doc or the implementation. Stuff like that we can avoid when either doc is generated from source or source is generated from doc. I think the most natural is that doc or design should generated base classes for implementation. Good tooling around this is thus very welcome.
    Great talk 👍. Baby steps.

  • @weifengmao
    @weifengmao 11 หลายเดือนก่อน +3

    Minimal API does address some of the issues when it comes to attributes.
    Also if you enable GenerateDocumentationFile in proj file NSwag does produce descriptions/summaries from code comments

    • @RFalhar
      @RFalhar 11 หลายเดือนก่อน +2

      Not just minimal API. All controllers and their endpoints along with request/response structures do that.

    • @weifengmao
      @weifengmao 11 หลายเดือนก่อน

      @@RFalhar Not if you have multiple response types/statuscodes

    • @RFalhar
      @RFalhar 11 หลายเดือนก่อน +2

      @@weifengmao Can you be specific? If you put comments on each response type, each response type should have proper comments.

    • @bangonkali
      @bangonkali 11 หลายเดือนก่อน +2

      @@weifengmao you can actually get even more sophisticated than what was presented in this video in terms of tweaking the output for nswag and redoc even in asp net core api with nswag (non-minimal-api).
      however, i agree that it does clutter up the controllers. in our projects, the controllers are typically docs filled with markdown comments and other specs as attributes, and the functional c# code they contain are 1-liner mediatr calls per method.
      there is merit to this presentation though hence why in my other comment I specifically encourage continuation of this project especially in the context of Design Rule Check wherein the yaml files are used to automatically check implementation if they are compliant with the YAML. And even better if similar to GRPC, base-classes can be created from the YAML files. this would be a good alternative way to work.
      THe most important aspect I think is that there has to be a consistent way to prove that DESIGN/DOC is equivalent with IMPLEMENTATION. without a good way to prove IMPLEMENTATION complies with DESIGN, or DESIGN was IMPLEMENTED correctly in an automatic fashion, then that is where everything fall apart.
      On a side note, there is not even a guarantee that YAML/OPENAPI JSON generated from NSWAG or Swashbuckle are correct. You can add configuration that messes this up. So a DESIGN RULE CHECK tool is still a really great tool to have anyway.

  • @awright18
    @awright18 11 หลายเดือนก่อน +3

    "REST was a stupid idea and we are not doing it"

  • @Marfig
    @Marfig 10 หลายเดือนก่อน +1

    We've been using OpenAPI for 4 or 5 years now. But as far as linting my API goes, it doesn't help that the current implementation is slow to fix its issues, namely stopping from coming up with its own set of HTTP rules that either differ or are more restrict than what RFC 7231 establishes. As an example, the fact that OpenAPI returns an error if I add a body to my DELETE statement. I'd rather have a linting program that doesn't try to set the language rules. And, I know what someone could be saying next... let me tell you, occasionally you might need a body in your DELETE request, something that RFC 7231 explicitly says is up for the implementation to decide whether they allow it. And lo and behold, you can find legacy code, including good ol' Active Directory, that does require a message payload in your delete requests.

  • @AftercastGames
    @AftercastGames 11 หลายเดือนก่อน +1

    This makes me miss WCF. Click Add Reference, copy paste a URL, and you’re done. Those were the days.
    Nowadays, the absolute best experience I can expect is to copy paste a URL into a browser, and get back JSON that’s actually readable, and then write code to expect that JSON.
    All of this version controlled documentation/specification document parsing chaos is insanity. If it doesn’t make your job easier, why do it?

  • @anomalii7720
    @anomalii7720 11 หลายเดือนก่อน +2

    "You're Doing It Wrong."
    Sure ....We always Do Everything Wrong.

  • @Thatoneguy-o7805
    @Thatoneguy-o7805 9 หลายเดือนก่อน

    Woof. The comments on this video are rough.
    "We dont lock in a spec before we write the code so this won't work for us. We dont see an issue with that previous sentence."

  • @fotofoxes2255
    @fotofoxes2255 10 หลายเดือนก่อน +1

    It looks like, the guy loves pain in the ass when doing his work. I personally prefer working on the immediate business problem rather than diverting to any infrastructure issues.

  • @Marfig
    @Marfig 10 หลายเดือนก่อน +5

    Separate Design and Implementation... that too was a terrible idea and we aren't doing it.
    I'd like people to stop advocating this. Come down from your ideal world and get into the real world, where stakeholders, product owners and project managers, will make sure you can never separate these two things because their only job is to change your requirements faster than you can type your code in. Not to mention the almost certain probability of your company having no software architects or designers anywhere to be seen and putting the burden of problem-solving on inexperienced team leads and teams composed primarily of junior developers.
    This type of advice just makes everyone to whom this is just an unattainable goal feel like they are absolute shite. When in fact they are not the ones that should be listening to it. You want to separate design from implementation? Don't say it to a panel of developers.

    • @oberlinio
      @oberlinio 10 หลายเดือนก่อน

      Now getting into OpenAPI, I do not view it as separating design and implementation. It’s more like “design first” via the OpenAPI doc. And as changes come down the pipeline, part of the triage is updating the OpenAPI doc. Then your internal code can work off that doc. Junior or not, one out to be designing some structure as they code - like any writer of any level is expected to be able to produce an outline of their article

    • @Marfig
      @Marfig 10 หลายเดือนก่อน

      @@oberlinio The problem is that design-first only works during your first stages of API development. Once you start adding features on the same cadence of your sprints, you'll have to face the usual corporate disorganization which is much slower to adopt Agile principles (if they ever do). So you are getting constant updates to requirements mid-sprint, among other shenanigans, and before you notice it, you are doing code-first and dropped design-first entirely. At that point, you start wondering why you are using OpenAPI which is no longer a driving force for your code, when you should be using Swagger or some other tool that is a better fit for code-first APIs, until the day OpenAPI offers us code-first tooling.

    • @oberlinio
      @oberlinio 10 หลายเดือนก่อน

      @@Marfig thanks for the reply and insight. I may be underestimating how difficult it is to update a YAML file in certain work environments.

    • @Marfig
      @Marfig 10 หลายเดือนก่อน

      @@oberlinio The actual update of the YAML file is, of course, not the problem. As you try to hint, there's no real challenge in doing this. Instead that the problem is said YAML file -- or if you will, the continuous maintenance of an API schema as an external document to your code -- is not well suited for code-first scenarios, which is invariably how your API ends being developed, whether you want it or not. In my 30 years of software development, I never, even once, worked for a company outside of the software industry, that didn't struggle with their understanding and their attempts to accommodate the process requirements of their IT departments, be it waterfall or agile.
      My argument is that OpenAPI serves well design-first approaches to API development. But is not an improvement over Swagger and code annotations when you are doing code-first development. And while design-first could be seen as a superior approach, it requires an organization in your workplace that the vast majority of corporations outside of the software development industry simply don't have. Something that this talk (and many others where similar bootless advice is given) doesn't address at all.

  • @xpflutebox
    @xpflutebox 11 หลายเดือนก่อน +4

    So tired of these "you're doing it wrong" clickbait talks

  • @hassejansson
    @hassejansson 11 หลายเดือนก่อน +2

    Hey, don't waste your time with this, this was a pretty bad talk.. :/ 50 minutes wasted...

    • @TeamDman
      @TeamDman 10 หลายเดือนก่อน

      I thought it was good, I haven't used open api yet so this was a good overview