-
Notifications
You must be signed in to change notification settings - Fork 372
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] Add basic rules for routes #1245
Open
andrewnicols
wants to merge
1
commit into
moodle:main
Choose a base branch
from
andrewnicols:pageRoutingRules
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
--- | ||
title: Routing Policies | ||
tags: | ||
- Processes | ||
- Core development | ||
- Policy | ||
- Routing | ||
- Pages | ||
--- | ||
|
||
This document describes the policies for route naming in Moodle. | ||
|
||
Routes are a powerful feature introduced in Moodle 4.5, and further extended in Moodle 5.0 which allow parts of Moodle, including plugins, to generate content without an explicit PHP endpoint file directly hit by users. | ||
|
||
See the [Routing system documentation](/docs/apis/subsystems/routing) for further information. | ||
|
||
Routes are currently used in the following places: | ||
|
||
- The REST API | ||
- End user content (pages) | ||
- Shims to redirect legacy locations to new pages (shims) | ||
|
||
Part of the URL used to access these pages is automatically generated by the component that the route is a part of, but the remaining part is generated by the developer. | ||
|
||
To ensure consistency across Moodle, and to mitigate the risk of route shadowing, Moodle follows some rules for route paths. | ||
|
||
Routes are typically comprised of: | ||
|
||
- the component prefix | ||
- an _entity_ type, for example `course` | ||
- an entity _identifier_, for example `948` | ||
- an _action_ on that entity, for example `view` | ||
|
||
Some of these parts may not be required, depending on the component and route type. | ||
|
||
## The Component {#component-naming} | ||
|
||
Where a component is present in the URL, the value is automatically determined from the location of the class defining the route. | ||
|
||
:::tip Component Appearance | ||
|
||
Where the component is a plugin, the full Frankenstyle Plugin Name is used, for example `mod_assign`. | ||
|
||
Where the component is a core subsystem such as `core_course` then the `core_` prefix is removed, for example `course`. | ||
|
||
::: | ||
|
||
## Entity types | ||
|
||
In many cases the component will be the entity, for example in the `core_course` component, the primary entity is the course. This is referred to as the _default_ entity. | ||
|
||
The following are examples of a default entity: | ||
|
||
``` title="The core_course subsystem has a default entity of 'course'" | ||
/rest/api/v2/course/<courseid> | ||
/course/<courseid>/view | ||
``` | ||
|
||
The following are examples of a non-default entity: | ||
|
||
``` title="The core subsystem does not have any default entity" | ||
/rest/api/v2/core/templates/<theme>/<templateName> | ||
/rest/api/v2/core/strings/<language>/<stringComponent>/<stringIdentifier> | ||
``` | ||
|
||
:::danger Default and non-default entities | ||
|
||
The use of both a _default_ entity _and_ a non-default entity is not officially supported. | ||
|
||
::: | ||
|
||
:::tip Singular or Plural | ||
|
||
Where present, entities should always be in the plural form. | ||
|
||
::: | ||
|
||
## REST API Route Paths {#rest-route-paths} | ||
|
||
All REST paths follow the following format: | ||
|
||
``` | ||
/rest/api/v2/<component>/<path> | ||
``` | ||
|
||
:::tip | ||
|
||
The [standard rules](#component-naming) for `component` formatting apply. | ||
|
||
::: | ||
|
||
### Action verbs on the REST API | ||
|
||
In most cases the REST API will make use of different HTTP Methods to dictate the relevant actions, for example: | ||
|
||
- `GET` to fetch data | ||
- `POST` - create data | ||
- `DELETE` to delete data | ||
|
||
Therefore the use of action verbs in REST API paths is strongly discouraged. | ||
|
||
### Sub-entities on the REST API | ||
|
||
In many cases an entity may have related child entities, or _sub-entities_. These should be placed after the primary or default entity's identifier, for example: | ||
|
||
``` | ||
/rest/api/v2/course/<courseid>/section/<sectionid> | ||
``` | ||
|
||
## Page Route Paths | ||
|
||
Moodle 5.0 adds support for page routes. Page routes allow a standard Moodle page to be served without the user visiting a PHP page explicitly created for that purpose. | ||
|
||
Page routes make use of the Routing engine to manage their complete end-to-end workflow. | ||
|
||
All Page routes follow the following format: | ||
|
||
``` | ||
/<component>/<path> | ||
``` | ||
|
||
:::tip | ||
|
||
The [standard rules](#component-naming) for `component` formatting apply. | ||
|
||
::: | ||
|
||
### Action verbs on Page Routes | ||
|
||
In the case of Page Routes, it is not possible to use HTTP methods. Instead an action verb should be specified. | ||
|
||
:::tip | ||
|
||
The action should be specified _after_ the identifier, for example: | ||
|
||
``` | ||
/course/<identifier>/<action> | ||
``` | ||
|
||
::: | ||
|
||
Action verbs should be single, simple, words and clearly identify the purpose of that action, for example: | ||
|
||
- `view` | ||
- `edit` | ||
- `manage` | ||
- `delete` | ||
|
||
### Sub-entities on Page Routes | ||
|
||
In many cases an entity may have related child entities. These should be placed after the identifier of the primary entity, for example: | ||
|
||
``` | ||
/course/<courseid>/capabilities | ||
``` |
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree regarding plural form. Should examples for course entity be changed accordingly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to strictly follow the subsystems names here.
However, in the example of course,
/courses/<courseid>/view
sounds not correct, as you are only going to ever look at a singular course. So I think in this case singular is the way to go.Not sure how we make the docs clearer though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the moment the component resolution is automatic based on the location of the class and we automatically normalise it.
If we want to do something different then we'll have to work out the best way of doing so and in which situations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it is sounds not correct in individual scenario, unless one see it as query "select
<courseid>
from courses". Thinking in broader context, what will be the endpoint for querying list of courses? Different/courses
path or/course/list
action? Something better to consider while we are at early stage I guess :)With regard to this "tip", to avoid contradition for now we might say "Where possible, entities should be in the plural form."
PS In Martin Fowler's REST maturity model article all entities are plural (Level 1 onwards).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Andrew's point is a good one that resolution is based on automatic resolution. Messing around with that feels like it may add more complexity than it's worth.
Also, thanks for the extract context Ruslan