restsakai

Sakai: How do I get a site (course) listing with REST or WS interface?


I am trying to interface with Sakai from an external application in order to get read only course information (identifier, course name, description, instructor, etc.). It looks (/direct/site/describe) like the "site" REST service only expose things that need you to have the course ID already. I noticed while browsing the Sakai source there is a SiteService that has a method called getSites() which looks a lot like what I need but (disclaimer) I know almost nothing about Sakai. I just need this data.

My question is: This seems like something that should be there am I missing something? Also, is the best way forward just to expose the SiteService getSites through a custom service?


Solution

  • If you want to just get a listing of every site in a Sakai installation then you will have to build something custom since the complete listing of all sites is not a typical use case. Generally applications are more interested in getting the listing of sites which a specific user has access to. For example:

    http://nightly2.sakaiproject.org:8081/direct/site.json
    

    Will return the complete listing (possibly with paging) for the currently logged in user.

    {"entityPrefix": "site", "site_collection": [
    {
      "createdDate": 1401938965607,
      "createdTime": {
        "display": "Jun 4, 2014 11:29 pm",
        "time": 1401938965607
      },
      "description": null,
      "htmlDescription": "",
      "htmlShortDescription": "",
      "iconUrl": null,
      "iconUrlFull": null,
      "id": "61a1ebbd-e507-4ca3-8f88-65abca0803d9",
      "infoUrl": null,
      "infoUrlFull": null,
      "joinerRole": null,
      "lastModified": 1401938965993,
      "maintainRole": "maintain",
      "modifiedDate": 1401938965993,
      "modifiedTime": {
        "display": "Jun 4, 2014 11:29 pm",
        "time": 1401938965993
      },
      "owner": "admin",
      "props": {
        "contact-name": "Sakai Administrator"
      },
      "providerGroupId": null,
      "reference": "\/site\/61a1ebbd-e507-4ca3-8f88-65abca0803d9",
      "shortDescription": null,
      "siteGroups": null,
      "siteOwner": {
        "userDisplayName": "Sakai Administrator",
        "userEntityURL": "\/direct\/user\/admin",
        "userId": "admin"
      },
      "sitePages": [
        {
          "id": "e051601e-2162-47c1-9e04-63a033f56cdf",
          "layout": 0,
          "layoutTitle": "Single Column Layout",
          "position": 0,
          "props": {
            "is_home_page": "true"
          },
          "reference": "\/site\/61a1ebbd-e507-4ca3-8f88-65abca0803d9\/page\/e051601e-2162-47c1-9e04-63a033f56cdf",
          "siteId": "61a1ebbd-e507-4ca3-8f88-65abca0803d9",
          "skin": "neo-default",
          "title": "Home",
          "titleCustom": false,
          "url": "http:\/\/nightly2.sakaiproject.org:8081\/portal\/site\/61a1ebbd-e507-4ca3-8f88-65abca0803d9\/page\/e051601e-2162-47c1-9e04-63a033f56cdf",
          "activeEdit": false,
          "popUp": false
        },
        {
          "id": "2e7c2004-0dc2-47bc-8e55-ca1df8e58c33",
          "layout": 0,
          "layoutTitle": "Single Column Layout",
          "position": 1,
          "props": null,
          "reference": "\/site\/61a1ebbd-e507-4ca3-8f88-65abca0803d9\/page\/2e7c2004-0dc2-47bc-8e55-ca1df8e58c33",
          "siteId": "61a1ebbd-e507-4ca3-8f88-65abca0803d9",
          "skin": "neo-default",
          "title": "Assignments",
          "titleCustom": false,
          "url": "http:\/\/nightly2.sakaiproject.org:8081\/portal\/site\/61a1ebbd-e507-4ca3-8f88-65abca0803d9\/page\/2e7c2004-0dc2-47bc-8e55-ca1df8e58c33",
          "activeEdit": false,
          "popUp": false
        },
        {
          "id": "332c52a8-89fe-45bb-9b1a-bf6bace3e88a",
          "layout": 0,
          "layoutTitle": "Single Column Layout",
          "position": 2,
          "props": null,
          "reference": "\/site\/61a1ebbd-e507-4ca3-8f88-65abca0803d9\/page\/332c52a8-89fe-45bb-9b1a-bf6bace3e88a",
          "siteId": "61a1ebbd-e507-4ca3-8f88-65abca0803d9",
          "skin": "neo-default",
          "title": "Site Info",
          "titleCustom": false,
          "url": "http:\/\/nightly2.sakaiproject.org:8081\/portal\/site\/61a1ebbd-e507-4ca3-8f88-65abca0803d9\/page\/332c52a8-89fe-45bb-9b1a-bf6bace3e88a",
          "activeEdit": false,
          "popUp": false
        }
      ],
      "skin": null,
      "softlyDeletedDate": null,
      "title": "AZ",
      "type": "project",
      "userRoles": [
        "maintain",
        "access"
      ],
      "activeEdit": false,
      "customPageOrdered": false,
      "empty": false,
      "joinable": false,
      "pubView": true,
      "published": true,
      "softlyDeleted": false,
      "entityReference": "\/site\/61a1ebbd-e507-4ca3-8f88-65abca0803d9",
      "entityURL": "http:\/\/nightly2.sakaiproject.org:8081\/direct\/site\/61a1ebbd-e507-4ca3-8f88-65abca0803d9",
      "entityId": "61a1ebbd-e507-4ca3-8f88-65abca0803d9",
      "entityTitle": "AZ"
    },{
    ...
    

    Since you have a very specific use case, I would suggest you use the SiteService (or possibly even SQL) to retrieve the very limited data you are looking for and then add a new custom method to the SiteEntityProvider (https://source.sakaiproject.org/svn/entitybroker/trunk/core-providers/src/java/org/sakaiproject/entitybroker/providers/SiteEntityProvider.java) like so:

    @EntityCustomAction(action = "my_custom_method", viewKey = EntityView.VIEW_SHOW)
    public boolean myCustomMethod(EntityView view) {
        HashMap yourMap = new HashMap();
        // put code here to get all the sites data you need from the SiteService or the DB and then put the parts you want to return into a Map and then return that map
        return yourMap;
    }
    

    You could then call that method like so:

    http://nightly2.sakaiproject.org:8081/direct/site/my_custom_method.json