00:00:05.560
Thank you! I am really happy to be here. First of all, a big shout-out to the whole team behind this friendly and welcoming event. However, the introduction from Adrian and also this tweet bring quite a lot of pressure to be the only one with a sense of humor. Wow!
00:00:12.320
But have you seen the name of my talk? It’s about documentation, which might be the most boring thing in the world, at least in my opinion. So, prepare yourself for what might feel like a 40-year journey. I warn you! OK, let’s do the talk.
00:00:38.399
In the beginning, God created the heavens and the Earth. And REST didn't create the rest. I've condensed the timeline a bit, but that's essentially where our story begins. As web applications became more complex, we asked for more advanced ways to structure APIs. We designed many protocols like JSON API, GraphQL, and JRPC with strict rules and schemas.
00:01:05.400
However, the good old REST is still going strong, perhaps because the inner artist in us resists standardization. And there is no greater nemesis for our inner artist than documentation. Oh, there are so many problems with it! Here are a few examples to see if they resonate with you.
00:01:33.000
Do you ever feel afraid to open Slack due to endless API questions from outdated documentation? Are you tired from setting up Postman collections to manually test your API? Have you ever had to roll back an API update because it unexpectedly broke the front end? I promise we will find a solution in this talk.
00:02:08.080
And since it's 2023, can we find a solution in AI? There must be a way for us to avoid writing documentation. Let’s borrow Jason's talk idea and ask ChatGPT how to bring dinosaurs back to life using the GitHub API in Ruby.
00:02:15.000
That sounds like a crazy question, right? There is no way.
00:02:29.200
Just follow these four steps and suddenly we’re in Jurassic Park! Look, there’s even a Ruby snippet over there. And you know what’s even worse? Users might actually try that and come to you with complaints. Yes, I made that example up, but the whole story is real. You know that it's real.
00:02:37.959
So, I think there is no way for us to avoid writing documentation. Now that we're all on the same page, let’s discuss four key approaches to documenting APIs. We will spend the next few minutes discussing the pros and cons of each, starting with manually written documentation.
00:03:11.000
Manual documentation is straightforward; it just involves documenting our implementation after it’s already completed. However, this method is not only boring, but the resulting documentation is also constantly outdated and out of sync with the implementation. We could potentially fix that if we could somehow bind our documentation to our implementation.
00:03:36.879
We can do that with some DSLS. With this approach, we generate documentation out of our controllers using some DSLs, and now our documentation is always up to date, which is great. But there are still some downsides, starting with the fact that documentation is still ready only after the code is completed. Our controllers become cluttered with some magic DSLs containing metadata, making it not really readable.
00:04:07.159
Finally, there are no tests to assert that our generated documentation is valid. An obvious solution is to shift those DSLs to our tests using a test-first approach. Now we're writing our tests first and adding some magic DSL into that to generate documentation. This way, we can ensure that as long as our tests are accurate, our documentation will be too.
00:04:31.039
Despite the fact that documentation is ready before implementation, it still is only ready after the tests are written, which is a primary issue with both test-first and code-first approaches. Developers might simply overlook the documentation since it's considered an afterthought. I once worked at a company with many microservices, and those approaches were used, but sometimes, the generated documentation was unclear and contained function names instead of descriptions, omitted attributes, and other oversights. It seems no one cared, but we should care.
00:05:02.759
With a documentation-first approach, our focus shifts to creating comprehensive documentation before we start coding. I call it the documentation-first approach, but you can also call it schema-first or specification-first, as we're now writing not just a mere documentation but a comprehensive specification.
00:05:40.760
This fact opens a lot of possibilities for us. Not only can we generate documentation, but we can also test our applications against it, validate incoming requests from users, and so on. It allows us to enhance our workflow. We can draft a specification, discuss it with the team, and ensure that the API meets all necessary requirements.
00:06:07.880
Next, we can add tests to confirm that specification, and finally, we implement the API. The last two steps can be swapped depending on your preference for the test-driven development approach.
00:06:39.840
With the documentation-first approach, there are no magic DSLs, so our code and tests are clean and readable. Documentation is ready before implementation or tests, so we can receive feedback earlier from our team.
00:07:01.680
Ultimately, documentation serves as a specification. The only downside is that it might require a shift in workflow. In summary, considering problems like outdated documentation, lack of automated tests, and communication issues, the documentation-first approach stands out as the most effective and collaborative approach.
00:07:15.240
Now that we have discussed the theoretical approach, let’s see this approach in action. The first step is to choose a specification format, and there are plenty of options out there, but OpenAPI is the most popular one and arguably the de facto standard. We are going to use it today.
00:07:46.880
To learn more about OpenAPI, consider reading the Petor API. It’s a great example of a well-documented API using OpenAPI. While commonly used for demos and examples, it might be a bit complex for our needs today. Instead, we’re going to assume we already implemented some features, like a simple CRUD for animals, and we received positive responses from our users.
00:08:30.239
Our happy stakeholder, the CEO of the Ark, comes to us with a new feature request to implement a feed feature. The request is somewhat vague, but unfortunately, the CEO of the Ark is swamped with other tasks and can't address our questions immediately, so we should come up with something on our own.
00:09:04.000
I suspect the CEO wants us to implement a feed similar to Twitter's, you know, to make animals destroy each other online and not in real life. That's a reasonable assumption since social networks are popping up like mushrooms after the rain these days. Let’s describe that with OpenAPI.
00:09:43.200
This is a minimal OpenAPI document. Unfortunately, explaining every keyword and feature of OpenAPI would take forever and isn't the point of my talk, so instead, I will just demonstrate a couple more slides to show how it looks and feels.
00:10:05.280
We will add all necessary operations for our feed feature, and I think it’s a great idea to document in this manner—moving from top to bottom and adding more details with each next step.
00:10:35.280
Let’s do that with one of the requests here. We've added a response description for a successful response, and note that the schema keyword inside OpenAPI uses another standard, JSON Schema, which can be used to validate JSON even outside of OpenAPI. It's a great tool that's really readable and easy to understand.
00:10:43.600
However, it can be a bit verbose. To fix that, we can use references. Here, we are referencing a local component in this document, but it's also possible to reference external files or OpenAPI descriptions to avoid dealing with long lines of code.
00:11:05.920
Next, we can iterate on this specification, adding more keywords and features until we’re satisfied with the result. Yes, maybe we got a little overboard there, but I think it’s fine.
00:11:32.880
Since we are done with our specification, we can now leverage the OpenAPI ecosystem, starting with editors. Editing a specification in PowerPoint is fun, but there are other options to consider, like Swagger Editor, which is a web-based application that can be embedded in your application's development environment, or this VS Code extension from Redly.
00:12:24.000
Next, linters. I bet almost everyone in this room uses Rubocop daily, but do you lint your OpenAPI documents? If you don’t, you should! Spectral is the way to go! So even if you use code-first or test-first approaches, adding Spectral to your workflow and your CI/CD pipeline will elevate your documentation.
00:12:48.160
Next, our front-end team can start implementation right away using mock servers like Prism, and the whole team can benefit from beautiful documentation UI generators like Swagger UI and Redoc. There are many more OpenAPI tools in this list, but the most important tool is collaboration—collaboration with our whole team, with front ends, analytics, and stakeholders.
00:13:14.000
With documentation, it’s now easy to discuss and improve features. By the way, now that we've edited, linted, and rendered our documentation, let's show it to the CEO of the Ark. Awesome work! But I wanted a feed of animals, not the animals' feed!
00:13:46.560
It seems we've misunderstood the requirements. This kind of misunderstanding happens all the time in software development, and isn't it great that we used the documentation-first approach? We didn’t implement anything yet and got feedback earlier. Now we can just reiterate on the documentation and make it work.
00:14:17.680
Assuming we did it and our documentation is ready and approved, let’s take a look at our workflow again. We just finished with the two first steps. Next, we are going to add tests to confirm the specification and implement the API. Let’s look at gems that can help us with that.
00:14:37.760
Starting with commit, I’ve worked with that gem for a couple of years—it’s a great tool, but it lacks some features from OpenAPI and JSON Schema. Next, OpenAPI First and JSON Schemer. The JSON Schemer gem just got updated to fully support JSON Schema's latest version, and I bet OpenAPI First will be updated soon to fully support the latest OpenAPI 3.1.
00:15:05.760
Finally, Schuma, which is our choice for today. There are many advantages to using JSON Schemer and Schuma. First of all, it has full support for OpenAPI 3.1 and JSON Schema. It's flexible and extensible, comes with ARPEC helpers out of the box, and has a cool name with a reference to Elder Scrolls games. And I’m the author, so obviously, it’s a 100% unbiased opinion!
00:15:58.320
Now that you know the best gem on the blog, let me show you how to configure Schuma. We only need to specify the documentation path and include Schuma into our request specs. Now we can access our OpenAPI document through Schuma.
00:16:38.399
Try saying that 10 times faster! For example, we can validate against the specification. Here's an example with a simple test. We can ensure that our OpenAPI document is always valid.
00:17:02.799
But the most important part is that we can validate our endpoints with helpers that validate request parameters, headers, and body, conforming response schema that validates response status, headers, and body.
00:17:39.839
Finally, conform schema validates both request and response. We have a vanilla request spec, and there are no magic DSLs—just a couple of helpers that validate all those attributes. Just imagine doing that with plain Ruby!
00:18:15.360
That’s insane! With this approach, we can now TDD our way to the perfect implementation of our specification. That's basically it—we found the path to solid ground—the land without proper documentation.
00:19:07.920
I've been working hard for the past couple of months on the Schuma gem and just released the first version today. It already has lots of features, but there are many more to come. If you’re interested, please try it out and share your feedback with me.
00:19:42.560
Also, consider following the project on GitHub and get your portion of Schuma today.
00:19:57.919
Now to the last part of our talk, which covers tips and tricks. It's okay to begin with the documentation-first approach on only one endpoint. Once you and your team are comfortable with this new approach, you can expand it to the entire API.
00:20:13.680
For those transitioning from code-first or test-first approaches, generating OpenAPI documents from your existing code can serve as a solid starting point. I've been in both situations, and it's worked great for me.
00:20:40.960
Next, add Spectral to your workflow and CI/CD pipeline. Once you’ve done that, use custom linters to enforce your API design, like specifying your response or pagination format, and ensure consistency across your API.
00:20:59.760
There are also real-world examples of rule sets available in Spectral documentation, which you can use as references to learn more.
00:21:23.960
Finally, please read the JSON Schema keyword PC; that will definitely level up your validations. For example, there's an annotated properties keyword that you can use to avoid exposing internal attributes to your users, like password hashes.
00:21:43.840
Just add that keyword to your schemas to ensure that your API is safe. You can even use custom linter rules to enforce this.
00:22:13.440
Thank you for your attention! If you have any questions afterward, feel free. I left some great resources for you on OpenAPI and JSON Schema, as well as these great talks I really enjoyed.
00:22:45.120
To recap: consider using the documentation-first approach to enable collaboration and early feedback. Use OpenAPI to write specifications in a language-agnostic format, so you and your team have one common language.
00:23:05.560
Also, improve your documentation with linters and tools from the OpenAPI ecosystem. Finally, use Schuma to test your application against those OpenAPI documents to save time and effort, making your code and tests more readable and your API more stable.
00:23:32.080
I hope you like this approach. So when you return to your colleagues, you can say, 'Let there be docs!' and there will be docs, and you'll see that the docs are good and separated the light from the darkness.