API v2 Redux#2645
Draft
jnovack wants to merge 10 commits into
Draft
Conversation
00353bb to
777994e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR: Consolidate v1/v2 API into single router
The SHORT SHORT Version
/api/v2routes (currently only some verb changes)WWWAPI-GUIDELINES.mdoutlines the details of why this change is so wordy, as all the files were re-written to comply with the formatting, style and structure to maintain consistency between files (there's still more work to do...)What changed
www/api/index.php$apiVersionPrefixes = ['', '/v2']array anddispatch_all(string $path, string $method, string $fn)helper that registers a route under every version prefix in one call.require_once 'controllers/helpers.php'for the newgetJsonBody()utility.snake_case/ mixed-case to PascalCase (public functions) and camelCase (helpers), matching the merged controllers. No behavioral change.dispatch_get(...)calls todispatch_all(...)calls.dispatch_post('/v2/...')lines for routes that changed from GET to POST in v2 (all state-changing operations: start/stop/pause/resume playlist, sequence control, fppd restart/start/stop, system reboot/shutdown, git reset, event trigger, script run, file move/onUpload, network interface add).remoteActionGET handler toRemoteAction_v1(query-param format). Addeddispatch_post('/v2/remoteAction', 'RemoteAction')for the JSON-body v2 variant.addPluginEndpoints()to calldispatch_all()so plugins are automatically registered under both/plugin/...and/v2/plugin/....www/api/controllers/(16 files replaced)Replaced each v1 controller with its v2 counterpart. All changes are naming convention only — no behavioral differences:
snake_case→PascalCasecamelCaseEvery controller function's docblock now uses version-tagged route annotations instead of a single
@routetag:@route-v1 METHOD /pathand@route-v2 METHOD /pathdeclare per-version routes (paths are prefix-free; the generator prepends the server base URL).@badge-v1 "DEPRECATED" warningmarks v1-only GET variants as deprecated in the generated OpenAPI spec.@body-vN,@response-vN, and@deprecated-vNare also supported for version-specific overrides.Affected files:
cape,network,system,sequence,backups,playlist,settings,channel,configfile,files,events,scripts,git,plugin,audioaliases,pipewirewww/api/controllers/helpers.php(new)Moved from
www/api/v2/controllers/helpers.php. ContainsgetJsonBody(bool $required = true): ?array, a centralized JSON request-body parser used by POST handlers that previously calledfile_get_contents('php://input')ad hoc.www/api/controllers/proxies.phpAdded
RemoteAction_v1()shim that readsipandactionfrom$_GETquery parameters (v1 GET behavior). The existingRemoteAction()function reads from the JSON request body (v2 POST behavior).www/api/controllers/help.phpandwww/apihelp.php(removed)The legacy help controller and its front-end entry point have been deleted. API documentation is now served exclusively from the OpenAPI spec.
Spec/doc file reorganization
Moved v1 static files into a
www/api/v1/subdirectory to match the v2 layout:www/api/openapi.json→www/api/v1/openapi.jsonwww/api/api.html→www/api/v1/api.htmlOpenAPI tooling (
www/api/tools/)generate_openapi.pyrenamed togenerate_openapi_v1.py.generate_openapi_base.py— shared generator logic imported by bothgenerate_openapi_v1.pyandgenerate_openapi_v2.py. Parses the@route-vN/@badge-vN/@deprecated-vNdocblock tags and builds version-filtered specs from a single controller source.convert_endpoints.pydeleted (one-off migration tool, no longer needed).Test infrastructure
tests/playwright/fixtures/version.ts(new): exportsV1 = '/api',V2 = '/api/v2', andtestBothVerbVersions()helper. For routes where only the verb changed (identical logic), one assertion function is shared by two thin@v1/@v2tagged test wrappers. Routes where behavior changed (e.g.remoteAction) keep separate test functions.tests/playwright/tests/api-v2/*.spec.ts: verb-changed routes updated to usetestBothVerbVersions(); individual tests carry@coveredtags for coverage tracking.tests/playwright/scripts/check-api-coverage.ts: router path updated fromwww/api/v2/index.phptowww/api/index.php; filter updated to only match/v2/prefixed routes when diffing againstAPI_COVERAGE.md.tests/playwright/package.json: addedtest:api:v1andtest:api:v2scripts.@e2e,@security,@full,@schema...Backward compatibility
All v1 routes continue to respond at their original paths and with their original HTTP verbs. No v1 client is broken (hopefully...)
Fixed
v2/index.phpv2/sequence/{SequenceName}v2/controllers/files.phpv2/file/move/{fileName},v2/file/onUpload/{ext}/**GETv2/controllers/network.phpv2/network/interface/add/{interface}GETv2/controllers/plugin.phpv2/plugin/{RepoName}/upgradeGETfor a mutating operationv2/controllers/system.phpv2/system/reboot,v2/system/shutdown,v2/system/fppd/*GETv2/controllers/playlist.phpv2/playlists/*,v2/playlist/{PlaylistName}/start*GETinstead of a mutating verbv2/controllers/events.phpv2/events/{eventId}/triggerGETv2/controllers/proxies.phpv2/remoteActionGETquery endpointv2/controllers/scripts.phpv2/scripts/{scriptName}/run,v2/scripts/installRemote/{category}/{filename}GETv2/controllers/git.phpv2/git/resetGETv2/controllers/sequence.phpv2/sequence/{SequenceName}/start/{startSecond},v2/sequence/current/*GET