RESTful protocol

Web service protocols ::: webservice_restful
Maintained by Catalyst IT
A REStful webservice plugin for Moodle LMS This plugin allows Moodle's webservice interface to operate in a more RESTFul way. Instead of each webservice call having a URL query parameter define what webservice function to use, webservice functions are made available by discrete URLs.
Latest release:
1006 sites
298 downloads
27 fans
Current versions available: 3

A RESTful webservice plugin for Moodle LMS

This plugin allows Moodle's webservice interface to operate in a more RESTFul way.
Instead of each webservice call having a URL query parameter define what webservice function to use, webservice functions are made available by discrete URLS.

This makes it easier to integrate Moodle with modern interfaces that expect a RESTful interface from other systems.

This plugin also supports sending requests to Moodle webservices using the JSON format.

Finally, by default all Moodle webservice requests return the HTTP status code of 200 regardless of the success or failure of the call. This plugin will return 4XX series status codes if calls are malformed, missing data or unauthorised. This allows external services communicating with Moodle to determine the success or failure of a webservice call without the need to parse the body of the response.


Why make this Plugin?

There were two related reasons for making this plugin. The first was to solve a technical problem; interfacing Moodle to a service that required each Moodle webservice to be callable from a unique URL. The second was to advance the maturity of Moodle's webservice interface.

The "Richardson Maturity Model" (https://martinfowler.com/articles/richardsonMaturityModel.html) describes the maturity of a web applications API/ webservice interface in a series of levels.

Maturity Model

Moodle is currently Level 0 or in the "swamp of POX". As described be Fowler, Moodle "is using HTTP as a tunneling mechanism for your own remote interaction mechanism"

This plugin aims to extend the maturity of Moodle's webservice interface to "Level 1: Resources" by making each webservice function available as a discrete URL.


Supported Moodle Versions

This plugin currently supports Moodle:

  • 3.1
  • 3.2
  • 3.3
  • 3.4
  • 3.5

Moodle Plugin Installation

The following sections outline how to install the Moodle plugin.

Command Line Installation

To install the plugin in Moodle via the command line: (assumes a Linux based system)

  1. Get the code from GitHub or the Moodle Plugin Directory.
  2. Copy or clone code into: <moodledir>/webservice/restful
  3. Run the upgrade: sudo -u www-data php admin/cli/upgrade Note: the user may be different to www-data on your system.

User Interface Installation

To install the plugin in Moodle via the Moodle User Interface:

  1. Log into your Moodle as an Administrator.
  2. Navigate to: Site administration > Plugins > Install Plugins
  3. Install plugin from Moodle Plugin directory or via zip upload.

Moodle Plugin Setup

Once the plugin has been installed in Moodle, the following minimal setup is required:

  1. Log into your Moodle as an Administrator.
  2. Navigate to: Site administration > Plugins > Webservices > Manage protocols
  3. Enable the RESTful protocol by clicking the "eye icon" in the enable column for this protocol.

Moodle Webservice Setup

Follow these instructions if you do not currently have any webservies enabled and/or unfamiliar with Moodle webservices.

There are several steps required to setup and enable webservices in Moodle, these are covered in the Moodle documentation that can be found at: https://docs.moodle.org/34/en/Using_web_services

It is recommended you read through these instructions first before attempting Moodle webservice Setup.

Accepted Content Types

Data can be sent to Moodle webservices using the following encodings:

  • application/json
  • application/xml
  • application/x-www-form-urlencoded

Use the 'Content-Type' HTTP header to notify Moodle which format is being used per request.

Returned Content Types

Data can be received from Moodle webservices using the following encodings:

  • application/json
  • application/xml

Use the 'Accept' HTTP header to notify Moodle which format to return per request.

Differences to Moodle Standard Webservice Interface

When using the RESTful plugin there are several differences to other Moodle webservice plugins, these are summarised below:

  • Webservice function as URL (slash parameter) ** Instead of being passed as a query parameter webservice functions are passed in the URL, e.g. https://localhost/webservice/restful/server.php/core_course_get_courses this allows each webservice to appear as a unique URL endpoint.
  • Webservice authorisation token as HTTP header ** Instead of being passed as a query parameter, authorisation tokens are passed using the 'Authorization' HTTP Header.
  • Moodle response format as HTTP header ** Instead of being passed as a query parameter, the desired Moodle response format ispassed using the 'Accept' HTTP Header.

Sample Webservice Calls

Below are several examples of how to structure requests using the cURL command line tool.

JSON Request

The following example uses the core_course_get_courses webservice function to get the course with id 6. The request sent to Moodle and the response received back are both in JSON format.

To use the below example against an actual Moodle instance:

  • Replace the {token} variable (including braces) with a valid Moodle authorisation token.
  • Relace localhost in the URL in the example with the domain of the Moodle instance you want to use.

curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H 'Authorization: {token}' \
-d'{"options": {"ids":[6]}}' \
"https://localhost/webservice/restful/server.php/core_course_get_courses"

XML Request

The following example uses the core_course_get_courses webservice function to get the course with id 6. The request sent to Moodle and the response received back are both in XML format.

To use the below example against an actual Moodle instance:

  • Replace the {token} variable (including braces) with a valid Moodle authorisation token.
  • Relace localhost in the URL in the example with the domain of the Moodle instance you want to use.

curl -X POST \
-H "Content-Type: application/xml" \
-H "Accept: application/xml" \
-H 'Authorization: {token}' \
-d'
<root>
   <options>
      <ids>
         <element>6</element>
      </ids>
   </options>
</root>' \
"https://localhost/webservice/restful/server.php/core_course_get_courses"

REST / Form Request

The following example uses the core_course_get_courses webservice function to get the course with id 6. The request sent to Moodle is in REST format and the response received back is in JSON format.

NOTE: This plugin can only accept requests in REST format. Responses must be in JSON or XML format.

To use the below example against an actual Moodle instance:

  • Replace the {token} variable (including braces) with a valid Moodle authorisation token.
  • Relace localhost in the URL in the example with the domain of the Moodle instance you want to use.

curl -X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Accept: application/json" \
-H 'Authorization: {token}' \
-d'options[ids][0]=6' \
"https://localhost/webservice/restful/server.php/core_course_get_courses"

Mixed Request and Response

This Moodle webservice plug-in allows for requests and responses to be different formats.

The following example uses the core_course_get_courses webservice function to get the course with id 6. The request sent to Moodle is in JSON format and the response received back is in XML format.

To use the below example against an actual Moodle instance:

  • Replace the {token} variable (including braces) with a valid Moodle authorisation token.
  • Relace localhost in the URL in the example with the domain of the Moodle instance you want to use.

curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/xml" \
-H 'Authorization: {token}' \
-d'{"options": {"ids":[6]}}' \
"https://localhost/webservice/restful/server.php/core_course_get_courses"

The received response will look like:


<RESPONSE>
<MULTIPLE>
<SINGLE>
<KEY name="id"><VALUE>6</VALUE>
</KEY>
<KEY name="shortname"><VALUE>search test</VALUE>
</KEY>
<KEY name="categoryid"><VALUE>1</VALUE>
</KEY>
<KEY name="categorysortorder"><VALUE>10003</VALUE>
</KEY>
...

Error Examples

The following cURL example will generate various types of errors. These are useful when testing.

No Aauthorization Header

This request is missing the authorization header.


curl -i -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d'{"options": {"ids":[6]}}' \
"http://moodle.local/webservice/restful/server.php/core_course_get_courses"

Invalid Token

This request contains an invalid webservice token.


curl -i -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H 'Authorization: xxx' \
-d'{"options": {"ids":[6]}}' \
"http://moodle.local/webservice/restful/server.php/core_course_get_courses"

This request is missing the Accept header.


curl -i -X POST \
-H -i "Content-Type: application/json" \
-H 'Authorization: e71561c88ca7f0f0c94fee66ca07247b' \
-d'{"options": {"ids":[6]}}' \
"http://moodle.local/webservice/restful/server.php/core_course_get_courses"

Roadmap

The next big step will be to update the interface to "Level 2" that is support HTTP verbs, like get and post.
Which verb to use will likely be dependant on the ws function name that is being invoked.

If you have any suggestions for functionality, they can be requests by raising a GitHub issue: https://github.com/catalyst/moodle-webservice_restful/issues

Crafted by Catalyst IT

This plugin was developed by Catalyst IT Australia:

https://www.catalyst-au.net/

Catalyst IT

Contributing and Support

Issues, and pull requests using github are welcome and encouraged!

https://github.com/catalyst/moodle-webservice_restful/issues

If you would like commercial support or would like to sponsor additional improvements to this plugin please contact us:

https://www.catalyst-au.net/contact-us


Screenshots

Screenshot #0

Contributors

Catalyst IT (Lead maintainer)
Matt Porritt: Developer
Please login to view contributors details and/or to contact them

Comments RSS

Afficher les commentaires
  • Raj Kumar
    mar. 21 août 2018, 19:32
    I have followed all steps to enable web services and also generate a valid token but when I tried to run API call it gave me following error

    {"exception":"moodle_exception","errorcode":"noauthheader","message":"No Authorization header found in request sent to Moodle"}

    but I am sending a valid token in the header with other required information like below

    curl -X POST \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H 'Authorization: {4838e6771cdbfd1eefbf37b3839587d9}' \
    -d'{"options": {"ids":[2]}}' \
    "mydomain.com/webservice/restful/server.php/core_course_get_courses"

    please help
  • Matt Porritt
    mer. 22 août 2018, 06:23
    Hi Raj,
    Try removing the braces {} from around the auth token, as outlined in the documentation. If you have any other problems please raise an issue here: https://github.com/catalyst/moodle-webservice_restful/issues
  • Ryan Kendall
    lun. 1 avr. 2019, 15:23
    Hi Matt.. i have done what you said and I have been able to remove the braces {} a stated in the auth token . thanks as this was not posted by the http://www.epoxyflooringlasvegas.com/epoxy-floor-las-vegas/
  • Onno
    jeu. 16 mai 2019, 16:35
    The authorization header was stripped by my version of Apache 2, resulting in a noauthheader error. It worked when added this directive:
    SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

    I also encountered a contenttype header error, which I solved by adding this code to webservice/restful/locallib.php, line 164 (get_requestformat function):

    if (isset($_SERVER['CONTENT_TYPE'])) {
    $requestformat = ltrim($_SERVER['CONTENT_TYPE'], 'application/');
    } else {
    // Raise an error if content header not supplied.
    $ex = new \moodle_exception('notypeheader', 'webservice_restful', '');
    $this->send_error($ex, 400);
    }

    - This function originally expected a HTTP_CONTENT_TYPE header, but it was CONTENT_TYPE in my case (using the sample curl from this page).
  • B G
    lun. 17 juin 2019, 12:24
    Hello all,
    This plugin could be a life saver!!! I plan to use Office 365 Flow to interact with Moodle and having a RESTFUL API is key! Does anyone know if it works with Moodle 3.7?
  • B G
    lun. 17 juin 2019, 12:26
    Is there a SWAGGER like page anywhere to enumerate and test all the RESTFUL commands/methods?
  • B G
    lun. 17 juin 2019, 12:28
    Would anyone know if this plugin is more powerful/stable/easier to user, etc... than the .NET API Wrapper?
    http://coderespect.blogspot.com/2017/06/moodle-api-net-wrapper.html
    https://github.com/syedrizwanm/Moodle.API.Wrapper
  • Ryan Klingaman
    ven. 30 août 2019, 20:14
    I have this working from the notes above:
    curl -X POST \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H 'Authorization: 555' \
    -d'{"options": {"ids":[6]}}' \
    "https: //server/webservice/restful/server.php/core_course_get_courses"

    But I'm trying to convert that into a python request and keep getting back a 401 response:

    headers = {
    'content-type': 'application/json',
    'accept': 'application/json',
    'authorization': '5555'
    }

    body = {"options": {"ids":[6]}}

    url = 'https: //server/webservice/restful/server.php/core_course_get_courses'

    resp = requests.post(url, headers=headers, json=body)
    data = resp.json
    print(data)

    Does anybody see what I'm doing wrong here?
  • Ryan Klingaman
    sam. 31 août 2019, 00:13
    I got it working by using this code:

    import requests

    headers = {
    'Accept': 'application/json',
    'Authorization': '555',
    'Content-Type': 'application/json'
    }

    body = '{"options": {"ids":[6]}}'

    url = 'https: //server/webservice/restful/server.php/core_course_get_courses'

    resp = requests.get(url, headers=headers, data=body)
    print(resp)
    data = resp.json()
    print(data)

    The issue was the capitalization of the headers in Accept Authorization and Content-Type. If someone else sees this and copies it pay attention to the space in the url so that I wouldn't get denied by the spam server on these comments and change the authorization number and of course not store it in the scripts.
  • Marc Mathys
    dim. 29 mars 2020, 09:25
    Hi. Can this be used by a device to send/receive JSON data (files) and store it in moodle for later access by the device or user?
  • Ashok Kumar
    sam. 25 juil. 2020, 12:28
    Hi. I have created the webservice by following the documentation, I'm getting the token for the service i created but when i try to access this url 'https: //localhost/webservice/restful/server.php/core_course_get_courses' using the generated token im getting 404 Object Not found error.
  • Paul Gatewood
    mer. 16 déc. 2020, 03:19
    Does anyone have any idea why this plugin should not work together with the following plugin?

    https://moodle.org/plugins/local_wsgetroles

    Using the ootb invocation, I get back a list of roles:
    ============================================================
    curl --globoff ^
    -d "wstoken=YmZjNDA5ZDQ4NGM5OWE1OWYxYTlmODg5" ^
    -d "wsfunction=local_wsgetroles_get_roles" ^
    -d "moodlewsrestformat=json" ^
    "http://10.0.0.121/webservice/rest/server.php"
    ============================================================

    But using the following returns nothing:
    ============================================================
    curl --globoff ^
    -H "Content-Type: application/json" ^
    -H "Accept: application/json" ^
    -H "Authorization: YmZjNDA5ZDQ4NGM5OWE1OWYxYTlmODg5" ^
    "http://10.0.0.121/webservice/restful/server.php/local_wsgetroles_get_roles"
    ============================================================
  • Tom Tom
    lun. 4 janv. 2021, 06:07
    Does this work with Moodle 3.10?
  • Haris Mateen
    dim. 21 nov. 2021, 20:39
    Hi, do you have postman collection for all of the endpoints?
  • David Mudrák
    lun. 30 mai 2022, 03:53

    I am happy to announce that the plugin received the "Moodle Workplace ready" award after being tested and found useful by the Worplace team (MDLSITE-6684). Congratulations!

1 2
Please login to post comments