[PR #2671] [CLOSED] Initial OpenAPI spec - Collection endpoints #3767

Closed
opened 2026-04-25 00:16:59 +02:00 by adam · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/advplyr/audiobookshelf/pull/2671
Author: @nichwall
Created: 2/27/2024
Status: Closed

Base: masterHead: collection_routes_openapi_v1


📝 Commits (10+)

  • 4c11ca5 Added swagger-jsdoc
  • f41b1b6 Initial CollectionController OpenAPI spec
  • 5a248e6 Updated OpenAPI to 3.1.0
  • 223e156 Initial Python API tester
  • bb297a3 Updated null types in initial OpenAPI spec
  • 9bb264a Current version of generated API-spec
  • 4fff661 Cleaned up libraryId schema definition
  • fe33b4c Cleaned up mediaType schema
  • 0aba5e6 Cleaned up createdAt schema
  • f5e1e5f Added tags and other cleanup

📊 Changes

41 files changed (+8670 additions, -19 deletions)

View changed files

build-docs/api_runner.py (+276 -0)
build-docs/swagger-output.json (+4706 -0)
📝 package-lock.json (+226 -1)
📝 package.json (+1 -0)
📝 server/controllers/CollectionController.js (+276 -10)
📝 server/controllers/LibraryController.js (+105 -0)
📝 server/controllers/LibraryItemController.js (+25 -0)
📝 server/models/Collection.js (+0 -1)
📝 server/objects/Backup.js (+46 -0)
📝 server/objects/Collection.js (+47 -0)
📝 server/objects/DeviceInfo.js (+66 -0)
📝 server/objects/Feed.js (+75 -0)
📝 server/objects/FeedEpisode.js (+91 -0)
📝 server/objects/FeedMeta.js (+82 -0)
📝 server/objects/Folder.js (+35 -0)
📝 server/objects/Library.js (+117 -1)
📝 server/objects/LibraryItem.js (+119 -0)
📝 server/objects/Notification.js (+128 -0)
📝 server/objects/PlaybackSession.js (+144 -0)
📝 server/objects/Playlist.js (+106 -0)

...and 21 more files

📄 Description

PR Overview

This PR is initial work to get an OpenAPI 3.1 spec added to JSDoc comments in the source code. This work was based off of work initially done by @benonymity and information from @Sapd. The PR includes (most) of the schemas defined in the server/objects/ files based on the current Slate API documentation (which is out of date). I have not validated all of these schemas because I was only focusing on the ones required to get the collections endpoints to work. These other schemas still need to be cleaned up, such as the Minified, Normal, and Extended responses for data types and have better examples given, and I included them because it is a lot easier to edit an existing schema than writing them from scratch (and benonymity had already made those schemas from the Slate API docs, so this should include all of the schemas he worked on).

As per Sapd's initial recommendation, I am using swagger-jsdoc to generate YAML files directly from the source code, done by running node swagger.js in the root directory of the repository. The resulting specification, swagger-output.json, is located in build-docs/. I also have created a very poorly written api_runner.py script that I am using to test API endpoints. It's pretty hacky and I can remove it from the PR, but am including it for initial review to see if a cleaned-up version would be beneficial during this initial work.

I will continue working through updates for each of the endpoints and schemas. If we want to do this a different way that is okay with me, just trying to help get the ball rolling.

Further discussion

To simplify support for multiple API versions, I would like to use a route-based versioning strategy. I think we should provide separate specification files for each version instead of putting everything in the same file with various versions.

At some point, we will need to address documentation translations, as all official documentation is only in English. I am not sure how best to approach this, but it looks like the easiest way will be using overlays similarly to how the server/client strings are managed.

We should implement automated testing for the API spec. Initially, it only needs to validate request/response formatting to ensure the data types match up and conform to the spec. This will be useful during the API rewrite and future database changes as it will alert of data type changes without needing to constantly update tests for different internal data operations.

My current testing procedure

I have written a Python script which connects to a dev server through wiretap (https://pb33f.io/wiretap/), which performs validation of requests and responses against an OpenAPI spec. I have also put wiretap in between the dev client and server to alert me of endpoints that are not in the spec while navigating manually in the client (though right now there are many failures because I've been focusing on collections). This has been working well and wiretap has a Docker image we could use as part of automated testing, but I am not sure how the e2e testing will work in GH Actions so this automated testing would still need to happen in local dev environments right now.

The creator of wiretap has made the vacuum tool to lint OpenAPI specs. This has helped me identify duplicate descriptions or other issues with the generated spec. Both wiretap and vacuum are in active development, so they definitely have some bugs and features missing but are quick to set up and work well enough for my process.

We can switch to something like https://www.npmjs.com/package/chai-openapi-response-validator to integrate with the existing chai test framework, but that means we need to use OpenAPI 3.0 instead of 3.1 and am still not sure how well that testing will work as a GH Action.

Next steps

The only decision that needs to be made before completing the initial OpenAPI spec is whether we want to switch to 3.0 or continue with 3.1.
The following blockers need to be discussed before continuing with a new API version:

Additional reading on spec organization: https://blog.liblab.com/why-your-open-api-spec-sucks/


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/advplyr/audiobookshelf/pull/2671 **Author:** [@nichwall](https://github.com/nichwall) **Created:** 2/27/2024 **Status:** ❌ Closed **Base:** `master` ← **Head:** `collection_routes_openapi_v1` --- ### 📝 Commits (10+) - [`4c11ca5`](https://github.com/advplyr/audiobookshelf/commit/4c11ca5a55b71c7b62262df3205854df7aaa98bc) Added `swagger-jsdoc` - [`f41b1b6`](https://github.com/advplyr/audiobookshelf/commit/f41b1b64694ddba50f2ab74a34ced058ebe9d05e) Initial CollectionController OpenAPI spec - [`5a248e6`](https://github.com/advplyr/audiobookshelf/commit/5a248e6ce91a0cf61c93e49421b337a975c429dc) Updated OpenAPI to 3.1.0 - [`223e156`](https://github.com/advplyr/audiobookshelf/commit/223e15643d6c428566ffdee95cf4d8e37a33e4f4) Initial Python API tester - [`bb297a3`](https://github.com/advplyr/audiobookshelf/commit/bb297a302ee39d3f2584acd493bfd2e7af523190) Updated null types in initial OpenAPI spec - [`9bb264a`](https://github.com/advplyr/audiobookshelf/commit/9bb264ac43606385c2d2407e07d4bac54f27f52f) Current version of generated API-spec - [`4fff661`](https://github.com/advplyr/audiobookshelf/commit/4fff661834b3171fd37843564eb65e9f706b126d) Cleaned up libraryId schema definition - [`fe33b4c`](https://github.com/advplyr/audiobookshelf/commit/fe33b4c6a8f62345e06eafe7a69bde79f61a260f) Cleaned up `mediaType` schema - [`0aba5e6`](https://github.com/advplyr/audiobookshelf/commit/0aba5e62c87e39538adc81462a4a2e23a1cb59b7) Cleaned up `createdAt` schema - [`f5e1e5f`](https://github.com/advplyr/audiobookshelf/commit/f5e1e5f21bc385199242e7c60244488ecc7a231a) Added tags and other cleanup ### 📊 Changes **41 files changed** (+8670 additions, -19 deletions) <details> <summary>View changed files</summary> ➕ `build-docs/api_runner.py` (+276 -0) ➕ `build-docs/swagger-output.json` (+4706 -0) 📝 `package-lock.json` (+226 -1) 📝 `package.json` (+1 -0) 📝 `server/controllers/CollectionController.js` (+276 -10) 📝 `server/controllers/LibraryController.js` (+105 -0) 📝 `server/controllers/LibraryItemController.js` (+25 -0) 📝 `server/models/Collection.js` (+0 -1) 📝 `server/objects/Backup.js` (+46 -0) 📝 `server/objects/Collection.js` (+47 -0) 📝 `server/objects/DeviceInfo.js` (+66 -0) 📝 `server/objects/Feed.js` (+75 -0) 📝 `server/objects/FeedEpisode.js` (+91 -0) 📝 `server/objects/FeedMeta.js` (+82 -0) 📝 `server/objects/Folder.js` (+35 -0) 📝 `server/objects/Library.js` (+117 -1) 📝 `server/objects/LibraryItem.js` (+119 -0) 📝 `server/objects/Notification.js` (+128 -0) 📝 `server/objects/PlaybackSession.js` (+144 -0) 📝 `server/objects/Playlist.js` (+106 -0) _...and 21 more files_ </details> ### 📄 Description ## PR Overview This PR is initial work to get an OpenAPI 3.1 spec added to JSDoc comments in the source code. This work was based off of work initially done by @benonymity and information from @Sapd. The PR includes (most) of the schemas defined in the `server/objects/` files based on the current Slate API documentation (which is out of date). I have not validated all of these schemas because I was only focusing on the ones required to get the collections endpoints to work. These other schemas still need to be cleaned up, such as the Minified, Normal, and Extended responses for data types and have better examples given, and I included them because it is a lot easier to edit an existing schema than writing them from scratch (and benonymity had already made those schemas from the Slate API docs, so this should include all of the schemas he worked on). As per Sapd's initial recommendation, I am using `swagger-jsdoc` to generate YAML files directly from the source code, done by running `node swagger.js` in the root directory of the repository. The resulting specification, `swagger-output.json`, is located in `build-docs/`. I also have created a very poorly written `api_runner.py` script that I am using to test API endpoints. It's pretty hacky and I can remove it from the PR, but am including it for initial review to see if a cleaned-up version would be beneficial during this initial work. I will continue working through updates for each of the endpoints and schemas. If we want to do this a different way that is okay with me, just trying to help get the ball rolling. ## Further discussion To simplify support for multiple API versions, I would like to use a route-based versioning strategy. I think we should provide separate specification files for each version instead of putting everything in the same file with various versions. At some point, we will need to address documentation translations, as all official documentation is only in English. I am not sure how best to approach this, but it looks like the easiest way will be using overlays similarly to how the server/client strings are managed. We should implement automated testing for the API spec. Initially, it only needs to validate request/response formatting to ensure the data types match up and conform to the spec. This will be useful during the API rewrite and future database changes as it will alert of data type changes without needing to constantly update tests for different internal data operations. ### My current testing procedure I have written a Python script which connects to a dev server through `wiretap` (https://pb33f.io/wiretap/), which performs validation of requests and responses against an OpenAPI spec. I have also put wiretap in between the dev client and server to alert me of endpoints that are not in the spec while navigating manually in the client (though right now there are many failures because I've been focusing on collections). This has been working well and `wiretap` has a Docker image we could use as part of automated testing, but I am not sure how the e2e testing will work in GH Actions so this automated testing would still need to happen in local dev environments right now. The creator of wiretap has made the `vacuum` tool to lint OpenAPI specs. This has helped me identify duplicate descriptions or other issues with the generated spec. Both wiretap and vacuum are in active development, so they definitely have some bugs and features missing but are quick to set up and work well enough for my process. We can switch to something like https://www.npmjs.com/package/chai-openapi-response-validator to integrate with the existing chai test framework, but that means we need to use OpenAPI 3.0 instead of 3.1 and am still not sure how well that testing will work as a GH Action. ### Next steps The only decision that needs to be made before completing the initial OpenAPI spec is whether we want to switch to 3.0 or continue with 3.1. The following blockers need to be discussed before continuing with a new API version: - API versioning method - https://www.codemzy.com/blog/nodejs-api-versioning - Spec formatting - https://blog.treblle.com/documentatuin-in-api-versioning/#how-to-document-multiple-api-versions - Translations - https://github.com/OAI/OpenAPI-Specification/issues/1740 Additional reading on spec organization: https://blog.liblab.com/why-your-open-api-spec-sucks/ --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
adam added the pull-request label 2026-04-25 00:16:59 +02:00
adam closed this issue 2026-04-25 00:16:59 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/audiobookshelf#3767