Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: [FC-0074] centralize docs for the hooks extension framework #599

Merged
merged 15 commits into from
Nov 21, 2024
Merged
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 155 additions & 0 deletions source/developers/concepts/hooks_extension_framework.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
=========================
Hooks Extension Framework
=========================

What is the Hooks Extension Framework?
=======================================

Based on the `open-closed principle`_, this framework aims to extend the Open edX platform in a maintainable way without modifying its core. The main goal is to leverage the existing extension capabilities provided by the plugin architecture, allowing developers to implement new features to fit customer needs while reducing the need for core modifications and minimizing maintenance efforts.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Based on the `open-closed principle`_, this framework aims to extend the Open edX platform in a maintainable way without modifying its core. The main goal is to leverage the existing extension capabilities provided by the plugin architecture, allowing developers to implement new features to fit customer needs while reducing the need for core modifications and minimizing maintenance efforts.
Based on the :doc:`edx-platform:open-release-quince.master/concepts/extension_points`, this framework aims to extend the Open edX platform in a maintainable way without modifying its core. The main goal is to leverage the existing extension capabilities provided by the plugin architecture, allowing developers to implement new features to fit customer needs while reducing the need for core modifications and minimizing maintenance efforts.

Is there a reason this document is under the quince page tree, and not its own concept document?

Copy link
Member Author

Choose a reason for hiding this comment

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

^ Fixed: c953566


Hooks are a list of places in the Open edX platform where externally defined functions can take place. These functions may alter what the user sees or experiences on the platform, while in other cases, they act as notifications. All hooks are designed to be extended through `Open edX Django plugins`_ and configurations.

Hooks can be of two types: events and filters. Events are signals sent in specific places whose receivers can extend functionality, while filters are functions that can modify the application's behavior. To allow extension developers to use these definitions in their implementations, both kinds of hooks are defined in lightweight external libraries:

* `openedx-filters`_
* `openedx-events`_

The main goal of the framework is that developers can use it to change the platform's functionality as needed and still migrate to newer Open edX releases with little to no development effort. So, the framework is designed with stability in mind, meaning it is versioned and backward compatible as much as possible.

A longer description of the framework and its history can be found in `OEP 50`_.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
A longer description of the framework and its history can be found in `OEP 50`_.
A longer description of the framework and its history can be found in :doc:`openedx-proposals:architectural-decisions/oep-0050-hooks-extension-framework`

This will make it a bit more resilient of a link

Copy link
Member Author

@mariajgrimaldi mariajgrimaldi Nov 6, 2024

Choose a reason for hiding this comment

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

Would this work for all documents under docs.openedx.org? I'm not sure how this cross referencing works.

EDIT: now I know:

intersphinx_mapping = {

Copy link
Member Author

Choose a reason for hiding this comment

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

Thank you for the suggestion! Now I'm working with the intersphinx mapping instead: c953566


.. _OEP 50: https://open-edx-proposals.readthedocs.io/en/latest/oep-0050-hooks-extension-framework.html
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
.. _OEP 50: https://open-edx-proposals.readthedocs.io/en/latest/oep-0050-hooks-extension-framework.html

Copy link
Member Author

Choose a reason for hiding this comment

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

Done! Now I'm working with the intersphinx mapping instead: c953566

.. _openedx-filters: https://github.com/openedx/openedx-filters
.. _openedx-events: https://github.com/openedx/openedx-events
.. _open-closed principle: https://docs.openedx.org/projects/edx-platform/en/open-release-quince.master/concepts/extension_points.html
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
.. _open-closed principle: https://docs.openedx.org/projects/edx-platform/en/open-release-quince.master/concepts/extension_points.html

Copy link
Member Author

Choose a reason for hiding this comment

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

^ Done! c953566


Why adopt the Hooks Extension Framework?
========================================

Stable and Maintainable Extensions
----------------------------------
Copy link
Contributor

Choose a reason for hiding this comment

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

Use =

Copy link
Member Author

@mariajgrimaldi mariajgrimaldi Nov 6, 2024

Choose a reason for hiding this comment

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

Thank you, you can review the changes here: a88af4d


The Hooks Extension Framework allows developers to extend the platform's functionality in a stable, maintainable, and decoupled way ensuring easier upgrades and long-term stability by removing the need to modify the core in an significant way.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
The Hooks Extension Framework allows developers to extend the platform's functionality in a stable, maintainable, and decoupled way ensuring easier upgrades and long-term stability by removing the need to modify the core in an significant way.
The Hooks Extension Framework allows developers to extend the platform's functionality in a stable, maintainable, and decoupled way ensuring easier upgrades and long-term stability by removing the need to modify the core in a significant way.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thank you again! c953566


Contained Solution Implementation
---------------------------------
Copy link
Contributor

Choose a reason for hiding this comment

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

Use =

Copy link
Member Author

@mariajgrimaldi mariajgrimaldi Nov 6, 2024

Choose a reason for hiding this comment

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

Thank you, you can review the changes here: a88af4d


By avoiding core modifications, the framework promotes self-contained solutions, eliminating the need for custom code to coexist with core logic which lowers maintenance costs for extension developers.

Leveraging the Open edX Plugin Extension Mechanism
--------------------------------------------------
Copy link
Contributor

Choose a reason for hiding this comment

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

Use =

Copy link
Member Author

@mariajgrimaldi mariajgrimaldi Nov 6, 2024

Choose a reason for hiding this comment

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

Thank you, you can review the changes here: a88af4d


The framework allows developers to implement custom business logic and integrations directly in plugins. This keeps core modifications minimal, focusing maintenance and development efforts on plugins, where solutions can be built and maintained independently of the core platform.

Standardization
---------------
Copy link
Contributor

Choose a reason for hiding this comment

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

Use =

Copy link
Member Author

@mariajgrimaldi mariajgrimaldi Nov 6, 2024

Choose a reason for hiding this comment

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

Thank you, you can review the changes here: a88af4d


Both filters and events implementations implement an approach for adding additional features, such as communication between services or backend flow control. With these standards in place, it’s easy to identify when and how to use the framework as a solution, ensuring a consistent and predictable approach to extending the platform.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Both filters and events implementations implement an approach for adding additional features, such as communication between services or backend flow control. With these standards in place, it’s easy to identify when and how to use the framework as a solution, ensuring a consistent and predictable approach to extending the platform.
The implementation of both filters and events allows for adding additional features, such as communication between services or backend flow control.

I don't really understand what the second sentence means (" With these standards in place, it’s easy to identify when and how to use the framework as a solution, ensuring a consistent and predictable approach to extending the platform.") - could you explain what you're trying to convey, so I can suggest a rewording? I'm particularly unsure of what "these standards" means.

Copy link
Member Author

@mariajgrimaldi mariajgrimaldi Nov 4, 2024

Choose a reason for hiding this comment

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

Events and filters are used for 1. Communication and 2. Application behavior modifications, respectively. So, if a problem can be solved with one of those two options, then the implementation would be pretty straightforward—at least the extension part of it. This would give developers a standard for extensibility if the use case fits what I previously mentioned. Does it make sense? I'll work on phrasing that a bit better.

Copy link
Member Author

Choose a reason for hiding this comment

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

What do you think about using this instead?

Filters and events provide developers with a standard for adding new features to the platform through extension mechanisms. Events primarily handle communication or synchronization between different parts of the application, while filters modify application behavior. If a problem can be addressed through one of these two options, the implementation becomes pretty straightforward.

I'm not quite sure if "Standardization" is the best title for this, though.

Copy link
Member Author

Choose a reason for hiding this comment

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

@sarina: what do you think about my latest suggestion?


Reduce Fork Modifications
-------------------------
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this section is needed, it's very close to the Contained Solution Implementation section. Maybe just add a sentence about forks in that section.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed. I think having it in the contained solutions section would be more impactful: c953566


The need to modify logic in forks is minimized, as most extensions can now be implementing using the framework, keeping forks closer to the core and easier to manage.

Community Compatibility
------------------------
Copy link
Contributor

Choose a reason for hiding this comment

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

Use =

Copy link
Member Author

@mariajgrimaldi mariajgrimaldi Nov 6, 2024

Choose a reason for hiding this comment

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

Thank you, you can review the changes here: a88af4d


The framework allows for shorter and more agile contribution cycles. By adding standardized extension points, contributors avoid creating customer-specific logic, making development more community-friendly.

Backward Compatibility
-----------------------
Copy link
Contributor

Choose a reason for hiding this comment

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

Use =

Copy link
Member Author

@mariajgrimaldi mariajgrimaldi Nov 6, 2024

Choose a reason for hiding this comment

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

Thank you, you can review the changes here: a88af4d


Hooks are designed to be backward compatible, guaranteeing stability across releases and making it easier to upgrade without breaking existing functionality.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Hooks are designed to be backward compatible, guaranteeing stability across releases and making it easier to upgrade without breaking existing functionality.
Hooks are designed to be backwards compatible, guaranteeing stability across releases and making it easier to upgrade without breaking existing functionality.

Does the framework provide an explicit guarantee to this effect?

Copy link
Member Author

@mariajgrimaldi mariajgrimaldi Nov 4, 2024

Choose a reason for hiding this comment

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

This is enforced by our versioning policy, e.g., https://github.com/openedx/openedx-events/blob/main/docs/decisions/0002-events-naming-and-versioning.rst#consequences. I'm going to refer to the ADR in the document.

Copy link
Member Author

Choose a reason for hiding this comment

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

^ Done: c953566


Open edX Events and Filters
============================
Copy link
Contributor

Choose a reason for hiding this comment

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

Use *

Copy link
Member Author

@mariajgrimaldi mariajgrimaldi Nov 6, 2024

Choose a reason for hiding this comment

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

Thank you, you can review the changes here: a88af4d


Open edX Events
----------------
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
----------------
============

Copy link
Member Author

@mariajgrimaldi mariajgrimaldi Nov 6, 2024

Choose a reason for hiding this comment

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

Thank you, you can review the changes here: a88af4d


Events are Open edX-specific Django signals sent in specific places on the Open edX platform. They allow developers to listen to these signals and perform additional processing based on the event data.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Events are Open edX-specific Django signals sent in specific places on the Open edX platform. They allow developers to listen to these signals and perform additional processing based on the event data.
Events are Open edX-specific Django signals sent in specific places on the Open edX platform. Developers write code that listens to these signals and performs additional processing based on the event data.

Copy link
Member Author

@mariajgrimaldi mariajgrimaldi Nov 7, 2024

Choose a reason for hiding this comment

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

Thank you for the suggestion! You can review the changes here: c953566


To start using Open edX Events in your project, see the `Open edX Events`_ documentation.

.. _Open edX Events: https://docs.openedx.org/projects/openedx-events/en/latest/
Copy link
Contributor

Choose a reason for hiding this comment

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

It'd be good to put this document in the intersphinx mapping (https://github.com/openedx/docs.openedx.org/tree/main/source#L67-L109) and reference it directly as a :doc:

Copy link
Member Author

Choose a reason for hiding this comment

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

Thank you! I actually asked how this cross-reference worked in one of my comments above, I'll review how this is done so I can use it!

Copy link
Member Author

@mariajgrimaldi mariajgrimaldi Nov 6, 2024

Choose a reason for hiding this comment

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

Sorry, I'm not sure where source#L67-L109 should take me to. I'll try to figure it out. Thank you!

EDIT: I did!

intersphinx_mapping = {

Copy link
Member Author

Choose a reason for hiding this comment

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

^ Done: c953566


Open edX Filters
-----------------
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
-----------------
================

Copy link
Member Author

@mariajgrimaldi mariajgrimaldi Nov 6, 2024

Choose a reason for hiding this comment

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

Thank you, you can review the changes here: a88af4d


Filters are functions that can modify the application's behavior by altering input data or halting execution based on specific conditions. They allow developers to implement application flow control based on their business logic or requirements without directly modifying the application code.

To start using Open edX Filters in your project, see the `Open edX Filters`_ documentation.

.. _Open edX Filters: https://docs.openedx.org/projects/openedx-filters/en/latest/
Copy link
Contributor

Choose a reason for hiding this comment

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

It'd be good to put this document in the intersphinx mapping (https://github.com/openedx/docs.openedx.org/tree/main/source#L67-L109) and reference it directly as a :doc:

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed! c953566


Differences between Events and Filters
---------------------------------------
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
---------------------------------------
=============================

Copy link
Member Author

@mariajgrimaldi mariajgrimaldi Nov 6, 2024

Choose a reason for hiding this comment

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

Thank you, you can review the changes here: a88af4d


Here are some key differences between Open edX Events and Filters:

+--------------------+------------------------------------------------------------------------+-------------------------------------------------------------+
| | Events | Filters |
+====================+========================================================================+=============================================================+
| **Purpose** | Notify when an action occurs in a specific part of the | Alter the application flow control. |
| | application. | |
+--------------------+------------------------------------------------------------------------+-------------------------------------------------------------+
| **Usage** | Used to **extend** functionality via signal handlers when an event is | Used to intercept and **modify** the data used within a |
| | triggered. | component without directly modifying the application |
| | | itself. |
+--------------------+------------------------------------------------------------------------+-------------------------------------------------------------+
| **Definition** | Defined using the ``OpenEdxPublicSignal``` class, which | Defined using the ``OpenEdxPublicFilter`` class, |
| | provides a structured way to define the data and | which provides a way to define the filter function |
| | metadata associated with the event. | and the parameters it should receive. |
+--------------------+------------------------------------------------------------------------+-------------------------------------------------------------+
| **Implementation** | Implemented using `Django signals`_, which allow | Implemented using an accumulative pipeline mechanism which |
| | developers to send and receive notifications that an action happened | takes a set of arguments and returns a modified set |
| | within a Django application. | to the caller or raises exceptions during |
| | | processing. |
+--------------------+------------------------------------------------------------------------+-------------------------------------------------------------+
| **Use cases** | Send an email notification when a user enrolls in a course. | Include additional information in an API endpoint response.|
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you provide a more detailed example for a filter?

Copy link
Member Author

Choose a reason for hiding this comment

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

I changed this example to "Prevent the enrollment of non-authorized users" c953566

| | an email notification. | |
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
| | an email notification. | |
| | | |

+--------------------+------------------------------------------------------------------------+-------------------------------------------------------------+

.. _Django signals: https://docs.djangoproject.com/en/4.2/topics/signals/

How to know when to use an Event or a Filter?
----------------------------------------------

When to use an Open edX Event?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----------------------------------------

Copy link
Member Author

@mariajgrimaldi mariajgrimaldi Nov 6, 2024

Choose a reason for hiding this comment

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

Thank you, you can review the changes here: a88af4d


Use an Open edX Event when but not limited to:

- Trigger custom logic or processing in response to specific actions within the platform, e.g., updating a search index after a course block is modified.
- Communicate, synchronize, or coordinate with other components or services based on specific events or actions, e.g., send certificate data from LMS to credentials service to keep models up to date.
- Integrate with external systems or services based on specific events or actions within the platform, e.g., send user data to third-party services upon registration for marketing purposes.

In summary, events can be used to integrate application components with each other or with external services, allowing them to communicate, synchronize, and perform additional actions when specific triggers occur.

You can review the `Open edX Events`_ documentation for more information on `how to use events`_ in your project. This documentation includes a `list of available events`_ and `how to implement event receivers`_.

.. _Open edX Events: https://docs.openedx.org/projects/openedx-events/en/latest/
.. _how to use events: https://docs.openedx.org/projects/openedx-events/en/latest/how-tos/using-events.html
.. _list of available events: https://docs.openedx.org/projects/openedx-events/en/latest/reference/events.html
.. _how to implement event receivers: https://docs.openedx.org/projects/openedx-events/en/latest/how-tos/using-events.html#receiving-events

When to use an Open edX Filter?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Use an Open edX Filter when but not limited to:

- Enrich the data or parameters passed to a specific component, e.g., fetch reusable LTI configurations from external plugins.
- Intercept and modify the input of a specific component, e.g., include "Edit" link to an HTML block if certain conditions are met.
Copy link
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 this is the best example of modifying a component. What are some others?

Copy link
Member Author

Choose a reason for hiding this comment

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

All these examples were extracted from a list of real-life use cases we've compiled: https://github.com/mariajgrimaldi/openedx-events-filters-analysis/blob/main/docs/Extensions_built_using_Hooks_Extensions_Framework.pdf. Since I'm writing the use-case list, that is just a filtered version of that document, I'll get some examples from there instead.

Copy link
Member Author

Choose a reason for hiding this comment

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

You can review the changes here: c953566

- Enforce specific constraints or business rules on the input or output of a specific function or method, e.g., prevent enrollment for non-authorized users.
- Implement additional features or behavior in a specific component, e.g., add custom logic to the user profile update process.

In summary, filters can be used when implementing application flow control that modifies the application's behavior, navigation, or user interaction flow during runtime.

You can review the `Open edX Filters`_ documentation for more information on `how to use filters`_ in your project or `create new filters`_. This documentation includes a `list of available filters`_ and `how to implement filter pipelines`_.

.. _Open edX Filters: https://docs.openedx.org/projects/openedx-filters/en/latest/
.. _how to use filters: https://docs.openedx.org/projects/openedx-filters/en/latest/how-tos/using-filters.html
.. _list of available filters: https://docs.openedx.org/projects/openedx-filters/en/latest/reference/filters.html
.. _how to implement filter pipelines: https://docs.openedx.org/projects/openedx-filters/en/latest/how-tos/using-filters.html#implement-pipeline-steps
.. _create new filters: https://docs.openedx.org/projects/openedx-filters/en/latest/how-tos/create-new-filters.html
.. _Open edX Django plugins: https://edx.readthedocs.io/projects/edx-django-utils/en/latest/plugins/readme.html