openwisp / openwisp/openwisp-utils
Harmonize REST API URL Naming and Availability
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 93
- Forks
- 104
- Avg merge
- 14h 10m
- Merged PRs (30d)
- 22
Description
⚠️ not suited for first time contributors/beginners.
Is this change related to a problem? Please describe.
Goal
Public REST URL naming and availability are inconsistent across OpenWISP Django modules. This change establishes one convention for public REST URL patterns and removes unsupported settings that conditionally register REST APIs.
This applies to Django URL pattern names used by reverse() and {% url %}. It does not rename view classes unless a separate reason requires that.
Scope
Audit and harmonize public URLConfs in:
- openwisp-users
- openwisp-controller
- openwisp-radius
- openwisp-firmware-upgrader
- openwisp-monitoring
- openwisp-notifications
- openwisp-ipam
- openwisp-subscriptions
- openwisp-network-topology
- openwisp-utils
- django-x509 where applicable
Do not include non-Django projects such as openwisp-config.
Current State
URL naming is inconsistent:
- Firmware Upgrader and Monitoring use
api_prefixes. - Controller, IPAM, Notifications, Network Topology, and Utils use generic names inside API URLConfs.
- RADIUS mixes
rest_and generic names. - Subscriptions mixes
api_and generic names.
The audit must identify every public route name, namespace, URL path, caller, test, documentation reference, and REST API route-gate setting before changing a module.
Describe the change
Decisions
Use the following conventions for implementation.
URL Naming
- Use one namespace per module for all public URLs:
users,controller,radius,upgrader,monitoring,notifications,ipam,subscriptions,topology,utils, andx509. - Prefix every REST URL pattern name with
api_to distinguish it from HTML and other non-REST views in the same namespace. - Name a REST route
api_<resource>_<action>, using singular, snake-case resource names. Uselistanddetailfor collection and object routes. - For a nested resource, include every semantic parent that scopes it:
api_<parent>_<resource>_<action>. - For an operation on a resource itself, use
api_<resource>_<action>without adding a child resource. - Do not include transport-only path segments such as
apiorv1in the name.
Examples: users:api_user_list, users:api_user_email_detail, controller:api_device_connection_list, monitoring:api_location_indoor_coordinates_list, and upgrader:api_build_firmware_download.
This keeps one predictable namespace per module while preventing collisions between REST and non-REST views and between similarly named nested resources.
REST API Availability
OpenWISP relies on REST APIs for internal and cross-module behavior. Public REST API URLs are mandatory and cannot be disabled.
- Do not introduce module-level settings that conditionally register public REST URLConfs.
- Retire existing public REST API route gates:
OPENWISP_USERS_AUTH_API,OPENWISP_CONTROLLER_API,OPENWISP_CONTROLLER_PKI_API,OPENWISP_RADIUS_API, andOPENWISP_FIRMWARE_UPGRADER_API. - Retain settings that configure a distinct concern, including API documentation, remote API URL configuration, API hosts, authentication requirements, and feature-specific registration behavior.
- Authentication, authorization, network controls, and rate limits remain the mechanisms for controlling API access.
Migration Policy
Treat renamed URL pattern names as a documented backward-incompatible change.
- Keep HTTP paths unchanged unless a separate API-versioning decision changes them.
- Publish a complete old-to-new
reverse()mapping in release notes and changelogs. - Update all maintained OpenWISP modules and sample projects in the same release cycle.
- Update tests, templates, Python callers, JavaScript configuration, and documentation references.
- Do not introduce aliases unless the maintainers decide that the affected release requires a compatibility window.
- If aliases are used, test both names and state their removal version.
Treat removal of a REST API route gate as a documented configuration migration.
- Do not silently register routes for deployments that explicitly set a retiring setting to
False. - Deprecate each setting before removal and provide a clear warning or configuration error that identifies the obsolete setting and its removal release.
- Update deployment templates and downstream settings that set a retiring setting.
Example mapping:
users:change_password -> users:api_user_password_change
users:user_list -> users:api_user_list
users:email_update -> users:api_user_email_detail
controller:deviceconnection_list -> controller:api_device_connection_list
upgrader:api_firmware_detail -> upgrader:api_build_firmware_detail
Implementation Plan
- Inventory every public production URLConf in scope.
- Record each route's path, current namespace, current name, view, callers, and documentation references.
- Confirm the canonical module namespace and naming convention, including semantic parents for nested routes.
- Inventory all settings, deployment templates, and downstream configuration that conditionally register public REST URLs.
- Define the old-to-new mapping for every affected module and the migration path for each retiring API route gate.
- Update each module's root URLConf and API URLConf consistently, removing public REST API route gates.
- Update all internal
reverse(),reverse_lazy(), templates, tests, and downstream OpenWISP callers. - Add regression tests that assert each canonical name, including nested resource names, resolves to the expected path and callback.
- Add migration tests for retiring API route gates, including configured
Falsevalues and deployment-template coverage where applicable. - If aliases are chosen, add equivalent regression tests for legacy names.
- Update module documentation and release notes with the complete migration mapping and configuration migration guidance.
- Run each affected module's focused URL tests, QA checks, and full suite.
Describe alternatives considered
A dedicated <module>_api namespace with unprefixed URL names would avoid collisions with non-REST views. One module namespace with api_-prefixed names provides the same protection with fewer namespaces and matches the existing module-level URL structure.
Making REST URLConfs independently optional was also considered. OpenWISP relies on REST APIs for internal and cross-module behavior, so omitting an API URLConf creates unsupported configurations that can fail when code reverses a required route. Access must instead be controlled through authentication, authorization, network controls, and rate limits.
Additional context
AGENTS.md Rule
Add this rule to every in-scope Django module's AGENTS.md:
Public REST URLConfs must use the module's project-wide namespace and snake-case
api_<resource>_<action>names. Nested resources must include every semantic parent that scopes them:api_<parent>_<resource>_<action>. Do not userest_prefixes or include transport-only path segments such asapiorv1in names. Changes to public URL paths or URL pattern names require a documented migration map, updated downstream callers, and compatibility tests or an explicitly announced backward-incompatible release.Public REST API URLs are mandatory. Do not add settings that conditionally register them. Retiring a public REST API route gate requires a documented configuration migration that does not silently expose routes for deployments that set it to
False.
Completion Criteria
- Every in-scope Django module follows the selected convention.
- No maintained OpenWISP repository uses an obsolete URL name.
- No in-scope module conditionally registers public REST URLs through an API enablement setting.
- Deployment templates and downstream settings no longer use retired REST API route gates.
- Release notes contain the full migration mapping.
- Each changed module passes URL regression tests, QA checks, and its full suite.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by inventorying the public production URLConfs, API URLConfs, route-gate settings, deployment templates, and AGENTS.md files across the listed OpenWISP Django modules. Trace each route name through reverse() callers, templates, tests, and documentation, recording the required migration map. Done means all scoped modules follow the naming convention, obsolete gates and references are migrated, regression and configuration tests pass, and release notes document the changes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- django, python
- Domain
- api, backend
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 25/100