Skip to content

[FC-0118] docs: migrate restful & legacy django api endpoints to standard drf viewsets - #38191

Merged
Faraz32123 merged 5 commits into
docs/ADRs-axim_api_improvementsfrom
docs/ADR-standardize_restful_api_endpoints_usage
Apr 21, 2026
Merged

[FC-0118] docs: migrate restful & legacy django api endpoints to standard drf viewsets#38191
Faraz32123 merged 5 commits into
docs/ADRs-axim_api_improvementsfrom
docs/ADR-standardize_restful_api_endpoints_usage

Conversation

@Faraz32123

@Faraz32123 Faraz32123 commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

This is an initial PR for an ADR to standardize restful api endpoints usage.
Currently, many Open edX platform API endpoints are implemented as separate, individual class-based or function-based views for each HTTP action. This ADR focuses on using Django REST Framework (DRF) ViewSets to group related operations into a unified, well-structured view classes.

Related issues: #38165, #38168

Comment thread docs/decisions/0028-standardize-restful-api-endpoints-using-drf-viewsets.rst Outdated
Comment on lines +19 to +23
Additionally, some endpoints currently return both JSON and HTML responses depending on
the request context. Serving both response formats from a single endpoint violates the
principle of separation of concerns, creates confusion for external consumers and
automated systems, and increases the complexity of both the view logic and client-side
handling.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if I agree with this, Content Negotiation is a pretty common thing and I think it makes more sense to have one endpoint that can provide content in multiple formats as necessary than two have different endpoints based on content types. I don't think we do this well right now, but I don't think it's because the underlying idea is bad but that we have implemented it in a rough way.

Separating the two endpoints also means we'd have to extract any business logic farther away from either endpoint so that we don't duplicate that for two endpoints that are meant to answer the same question in two formats.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have a valid point! I think we can remove this statement in favor of DRF Content Negotiation.
But do you think we can do something about legacy html pages(Link) that still don't have a react page in MFE experience or there is no such html page to worry about? I know most of them have a dedicated react page in MFE experience which we can toggle with a waffle flag.
And this statement was actually added in favor of our decision statement Additionally, all API endpoints will be standardized to return only JSON responses, with all HTML rendering logic relocated to dedicated Micro Frontend (MFE) pages. which will also require changes. If we don't want to go this way like looking for any page on frontend that still relies on HTML legacy experience, then its better to remove this statement.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this statement was actually added in favor of our decision statement Additionally, all API endpoints will be standardized to return only JSON responses, with all HTML rendering logic relocated to dedicated Micro Frontend (MFE) pages. which will also require changes. If we don't want to go this way like looking for any page on frontend that still relies on HTML legacy experience, then its better to remove this statement.

@feanil what do you think, should we remove this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Faraz32123 I don't quite understand what you mean here? Remove the whole Additionally... paragraph or some other smaller change?

@Faraz32123 Faraz32123 Apr 6, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@feanil I meant to say, should we focus on converting mako templates to MFE pages so that we have minimal no.of APIs that render HTML pages. But I think we can skip this part in favor of Content Negotiation which is quite common, let me completely remove this part.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think 99% of our APIs should return only JSON, and we may have one or two legacy endpoints that offer different formats like HTML, e.g. for rendering an XBlock, but in general it's not a pattern that we really need to support or standardize much as far as I know.

The related big problem we have, which I've mentioned in the error handling PR, is that some endpoints sometimes return HTML when a JSON response is expected, making debugging and error reporting much more difficult. Here is a real-world example from today, where the fairly technical user can't even see the error message because it's buried in HTML unexpectedly: https://discuss.openedx.org/t/unable-to-add-components-to-content-library/18782

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think both are different, HTML responses depending on the request context if its expecting return type to be HTML, then this should be allowed.
But in case of errors or where we don't need HTML in some legacy code where its not updated yet, it should be avoided & return proper JSON.
@bradenmacdonald Do you have any recommendation that we can add to this ADR?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're already discussing it on the other "error handling" ADR PR. But basically, if the client is expecting a JSON response, the server should never send HTML, regardless of what kind of error happens.

I agree this is a different question than "HTML responses depending on the request context", but I just wanted to mention it here.


* All related API actions (list, retrieve, create, update, delete) **MUST** be
consolidated into a single DRF ViewSet per resource.
* Endpoints currently returning both JSON and HTML **MUST** be refactored to return only

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flagging to update based on discussion in the above comment.

@feanil
feanil requested a review from MaferMazu March 27, 2026 13:11
@Faraz32123
Faraz32123 requested a review from feanil April 6, 2026 18:51

@MaferMazu MaferMazu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @Faraz32123, thanks for this ADR.

I added a few comments that I think are worth considering ✨

@@ -0,0 +1,229 @@
Standardize RESTful Endpoint Structure Using DRF ViewSets and also port legacy views to DRF endpoints

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Standardizing the RESTful Endpoint Structure Using DRF ViewSets and porting legacy views to DRF endpoints seem to me to be different decisions. Because standardization has its own context, consequences, and port the legacy to DRF, its own. Depending on what we need, I suggest separating this into two decisions.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we can separate both decisions.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MaferMazu, I have created a separate ADR(#38351) for porting legacy views to DRF and added you as reviewer there as well.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Faraz32123, thanks for splitting the ADRs based on my previous comment. I think I should clarify my point, as the current content still shares a similar goal (the decision section is too similar), which might lead to confusion during the review.

My suggestion to separate them was based on the fact that Standardization and Migration solve different problems: If the goal is only to migrate, we don't need two ADRs. One solid ADR focused on porting legacy views to DRF (like the enrollment example) is sufficient. We can remove 'Standardize' from the title and focus on the rollout and backward compatibility.

If we also have the goal of standardization, then the ADR for standardization should be a Definition of Architecture rather than an action plan. I imagine something like this Open edX REST API Conventions wiki doc, more of a definition of what we consider standard REST API in OpenedX, defining how an Open edX ViewSet must be built to be considered 'standard' (e.g., mandatory inheritance from edx-drf-extensions, explicit get_queryset optimizations, etc.).

My initial comment stemmed from the feeling that we were covering too much with a single ADR by trying to standardize and explain the migration decision. However, currently, both ADRs focus on action, which could be redundant. Depending on the scope, one or two ADRs are sufficient; if two, they should definitely address different decisions and objectives.

What do you think?

Related:
OEP-49
OEP-13

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MaferMazu yes, both ADRs focus on actions, Standardize RESTful Endpoint Structure Using DRF ViewSets was focusing on refactoring all fragmented Open edX REST API endpoints to use DRF ViewSets. And legacy views to DRF decision could also be covered under this same ADR. That's why I had added this commit(Link) to this ADR. I think titles could have stayed same in this commit that triggered the confusion & we were good to go.
I think If you agree, let's keep both in this same PR and I can remove the last commit with titles changed a bit.

If we also have the goal of standardization, then the ADR for standardization should be a Definition of Architecture rather than an action plan. I imagine something like this Open edX REST API Conventions wiki doc, more of a definition of what we consider standard REST API in OpenedX, defining how an Open edX ViewSet must be built to be considered 'standard' (e.g., mandatory inheritance from edx-drf-extensions, explicit get_queryset optimizations, etc.).

Yes the last goal is kind of same as @bradenmacdonald has also mentioned here in forum post(Link) to have a finalized OEP once all ADRs are accepted.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it is so, I agree with you to maintain that in one PR ✨

For the title, I suggest something clearer that aligns with the goal. - I ask Gemini, and there are some suggestions: Migrating Legacy Endpoints to Standard DRF ViewSets, Consolidating Legacy Django Views into DRF ViewSets, Adoption of DRF ViewSets for Legacy REST APIs, Refactoring Legacy API Views to Standardized DRF ViewSets, Transitioning Legacy Django Views to Unified DRF ViewSets.

You don't need to use one of those, but I think it is important to calibrate the expectation and the scope of this ADR. - Again, my first thought was you wanted to have this big oep ready + also document the migration decision. 🙈

* ViewSets **MUST** be registered using DRF Routers to ensure consistent, predictable
URL patterns.
* All ViewSets **MUST** use explicit serializers for both request validation and response
formatting (per ADR 0025).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add something like: "All ViewSets MUST optimize their get_queryset method using select_related and prefetch_related to match the fields required by their serializers, preventing N+1 query regressions."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to this, we should add to the rollout plan that it will be important to include a comparison of SQL query counts to ensure no performance degradation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its a good suggestions for APIs optimization perspective, I'll add it.


* Refactoring existing fragmented views into ViewSets requires non-trivial upfront
development effort.
* Existing URL patterns may change during migration, requiring updates to client-side

@MaferMazu MaferMazu Apr 10, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can mitigate this by developing a clear, structured migration plan. We should be explicit about the strategy we will have.
For example:

  • Release W: develop a v2 API following the DRF and add a deprecation tag
  • Release X, when v2 is stable: add a more aggressive warning while still supporting v1
  • Finally, in the next release, deprecate v1.

It doesn't need to be exactly like that, but it should allow the community to adapt their API endpoints without a crazy rush. In particular, the enrollment API is used across different OpenedX services and is also widely used for community plugins, so we should be conservative about it.

I think it is worth adding more details on the migration in the rollout plan.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can handle migration plan in this ADR: https://github.com/openedx/openedx-platform/pull/38304/changes and add a little bit of info here.

Muhammad Faraz Maqsood added 4 commits April 13, 2026 12:42
In this commit,
Instead of creating a new ADR, add decision for moving legacy Django views to DRF to similar existing ADR.
Its related issue is: #38168
@Faraz32123
Faraz32123 force-pushed the docs/ADR-standardize_restful_api_endpoints_usage branch from e74ab70 to 18a1817 Compare April 17, 2026 06:30
@feanil

feanil commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

I think this is ready to merge. @Abdul-Muqadim-Arbisoft you had a review that requested changes that I believe were made but wanted to confirm with you before we merge this.

@Abdul-Muqadim-Arbisoft Abdul-Muqadim-Arbisoft left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Faraz32123 Faraz32123 changed the title [FC-0118] docs: add ADR for standardizing restful api endpoints usage [FC-0118] docs: migrate restful & legacy django api endpoints to standard drf viewsets Apr 21, 2026
@Faraz32123
Faraz32123 merged commit 25e2724 into docs/ADRs-axim_api_improvements Apr 21, 2026
66 checks passed
@Faraz32123
Faraz32123 deleted the docs/ADR-standardize_restful_api_endpoints_usage branch April 21, 2026 09:38
Faraz32123 added a commit that referenced this pull request Jun 24, 2026
* docs: add ADR for standardizing serializer usage (#38139)

* docs: explicitly mention API versioning incase of backwards incompatible change (#38188)

Co-authored-by: Muhammad Faraz  Maqsood <faraz.maqsood@A006-01130.local>

* docs: add ADR for standardizing permissions usage (#38187)

Currently, authorization logic is implemented inconsistently across views, serializers, and custom access checks. This ADR will define a consistent approach using DRF permission classes, object-level permissions, and queryset scoping where appropriate.

Co-authored-by: Taimoor  Ahmed <taimoor.ahmed@A006-01711.local>

* docs: minor change in ADR language

* fix: add s back

* docs: migrate restful & legacy django api endpoints to standard drf viewsets (#38191)

* docs: Add ADR for ensuring GET requests are idempotent
Add edx-platform/docs/decisions/0030-ensure-get-requests-are-idempotent.rst as an accepted ADR.
Define policy that GET endpoints must be strictly read-only, with side effects moved to explicit write endpoints or async event pipelines.
Include edx-platform relevance, anti-pattern vs preferred code examples, and rollout guidance for testing and migration.

* docs: add ADR for standardizing API documentation and schema coverage

- Propose adoption of drf-spectacular across Open edX services
- Require @extend_schema decorators for all API endpoints
- Document request/response schemas, status codes, and error conditions

* docs: remove incorrect ADR number

* docs: address api-doc-tools deprecation in ADR per review feedback

- Add context explaining what api-doc-tools is and its relationship
  to drf-yasg
- Document deprecation and archival of api-doc-tools as a consequence
- Add migration guide mapping api-doc-tools decorators and URL helpers
  to their drf-spectacular equivalents
- Add rejected alternative for updating api-doc-tools internals
- Add rollout step for final archival cutover

Closes review comment by @feanil

* docs: expand ADR-0027 with api-doc-tools deprecation and drf-yasg incompatibility analysis

Address review feedback on FC-0118 ADR 0027:

- Add context paragraph explaining what api-doc-tools is (drf-yasg shim,
  decorators it provides, schema view, OpenAPI 2.0 output)
- Document deprecation of api-doc-tools and drf-yasg as a consequence,
  including transition-window behavior
- Add detailed 8-point incompatibility analysis explaining why drf-yasg
  cannot be replaced with drf-spectacular inside api-doc-tools (recorded
  in the ADR itself for future reference)
- Add migration plan for existing api-doc-tools consumers with concrete
  decorator/import/setting mapping
- Update Rollout Plan to track api-doc-tools removal
- Add references to drf-spectacular migration guide, drf-yasg upstream
  status, and api-doc-tools repository

* chore: fix edx-mantained to edX-platform

* docs: add ADR for standardizing pagination across APIs (#38300)

* docs: add ADR for api versioning strategy (#38304)

* docs: add ADR for standardizing filtering/sorting parameters (#38303)

* docs: add ADR-0029 standardized error responses decision (#38246)

* docs: add ADR for merging similar endpoints (#38262)

* docs: ADR for normalizing nested json apis (#38305)

* docs: add separate example for input & output serializers

* docs: ADR for documenting and consolidating internal MFE APIs (#38309)

* docs: ADR for documenting and consolidating internal MFE APIs
Define a plan to document all undocumented internal LMS APIs consumed
by MFEs into stable, OpenAPI-described contracts. Introduces a
consolidated config endpoint pattern with optional course/user context,
authentication boundaries, and a rollout plan following OEP-21 DEPR
process.

* docs: add ADR for canonical MFE configuration endpoint

Record that /api/frontend_site_config/v1/ is the canonical endpoint for
MFE/front-end runtime configuration (frontend-base SiteConfig, OEP-65) and
that /api/mfe_config/v1 is legacy, on the DEPR path tracked in #37255 and
added, and that user-context data (roles, permissions) belongs on
resource-oriented endpoints rather than on a configuration payload.
Documentation/schema coverage is deferred to the API Documentation &
Schema Coverage ADR (#38189).

Partially supersedes ADR 0001 (MFE Config API).

Part of FC-0118 Open edX REST API standardization (#38137).
Refs #38280

* docs: add ADR for standardizing authentication patterns (#38301)

* docs: add ADR for standardizing authentication patterns

* docs: resolve confusion & update the ADR based on OEP-0042

* docs: support multiple valid auth schemes & deprecate BearerAuthentication

* docs: change wording for decisions a bit.

* docs: add real examples in accordance with our updated decisions

* docs: sync ADR with edx-drf-extensions issue 284

openedx/edx-drf-extensions#284

* docs: make doc more explicit & address comments

* docs: move Bearer auth depr plan out of ADR

Move BearerAuthentication depr plan out of this doc So that it resides in single place i.e. to its deprecation ticket.

* docs: add a pointer file in oauth_dispatch for this ADR

* docs: make decision more clear

* docs: make authentication_classes usage more clearer

* docs: adress the comment related to session authentication

* chore: correct file number w.r.t order of the ADRs

---------

Co-authored-by: Muhammad Faraz  Maqsood <faraz.maqsood@A006-01130.local>
Co-authored-by: Taimoor Ahmed <68893403+taimoor-ahmed-1@users.noreply.github.com>
Co-authored-by: Taimoor  Ahmed <taimoor.ahmed@A006-01711.local>
Co-authored-by: Robert Raposa <rraposa@edx.org>
Co-authored-by: Abdul Muqadim <abdul.muqadim@A006-01811.local>
Co-authored-by: Abdul Muqadim <abdul.muqadim@192.168.1.7>
Co-authored-by: Abdul-Muqadim-Arbisoft <139064778+Abdul-Muqadim-Arbisoft@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants