"Populate" BB REST API option to return pre-populated data as full rendered documents

Idea created by mb23565 on May 30, 2017
    Under review
    Score0

    Hello,

     

    I would like to propose an option to the BB REST API query parameters to allow a user to request a full document rendering by adding a feature to the query; i.e.: ?populate=true&...other-filters...

     

    In the Mongoose ODM, there is an function called "populate" that will render out the full referenced document in its end result entirety. What I am noticing is that when requesting certain API routes, the data is only mirroring the tables from the database. This is ok if you want to re-create only portions of the Learn data in your application. But with newer methods and patterns approaching I find that this is counter productive. Since Learn is doing the heavy lifting of the CMS portion, I think that requesting a API should allow more high level overview of the data.

     

    For example: Course Users, Grades, etc.

     

    Let's say I am in need to view the all the course enrollments in a course by its external Id and that I wish to view the data in a more user friendly manner. So I make a request to /learn/api/public/v1/courses/externalId:LOR-CC-mbechtel/users. As of right now, I only receive the low level information:

     

    { 
         results: [
              { userId: '_43_1',
                courseId: '_2841_1',
                dataSourceId: '_2_1',
                created: '2014-03-04T14:24:49.000Z',
                availability: [Object],
                courseRoleId: 'Instructor' 
              },
              ....
    ]}
    
    
    

     

     

    Now, this is fine if you wish to re-create the relations. But when making a small application to relay information this information is almost useless.  Now let me show the proposed method with populate:

     

    /learn/api/public/v1/courses/externalId:LOR-CC-mbechtel/users?populate=true:

     

    {
      "course": {
        "_id": "58bdcb24d15ee7438247b82c",
        "updatedAt": "2017-03-06T20:48:36.965Z",
        "createdAt": "2017-03-06T20:48:36.965Z",
        "id": "_2841_1",
        "uuid": "ad842f780aa845879438a8cb0dd530dd",
        "externalId": "LOR-CC-mbechtel",
        "dataSourceId": "_1186_1",
        "courseId": "LOR-CC-mbechtel",
        "name": "LOR-CC-mbechtel",
        "created": "2014-03-04T14:24:14.000Z",
        "organization": false,
        "ultraStatus": "Classic",
        "allowGuests": true,
        "readOnly": false,
        "__v": 0,
        "locale": {
          "force": false
        },
        "enrollment": {
          "type": "InstructorLed"
        },
        "availability": {
          "available": "Yes",
          "duration": {
            "type": "Continuous"
          }
        }
      }, 
      results:
      [{
        "user":
        {
          "__v": 0,
          "id": "_43_1",
          "uuid": "022dd4e99f644267a4369cb66fcec25b",
          "externalId": "73099",
          "dataSourceId": "_2_1",
          "userName": "mbechtel",
          "educationLevel": "Unknown",
          "gender": "Unknown",
          "created": "2013-07-02T15:02:36.000Z",
          "lastLogin": "2017-05-30T13:30:43.000Z",
          "_id": "592d89f24a68f515c7cefabe",
          "contact": {
            "email": "mbechtel@irsc.edu"
          },
          "name": {
            "given": "Michael",
            "family": "Bechtel",
            "title": "System Admin"
          },
          "availability": {
            "available": "Yes"
          },
          "systemRoleIds": [
            "SystemAdmin"
          ]
        }
        ,
        "dataSource": '_2_1',
        "created": '2016-10-05T14:56:25.000Z',
        "availability": {
          "available": "Yes"
        },
        "courseRoleId": 'Instructor'
      },
        ....
     ] }
    
    
    

    So, the return information returns the course information as a top level key, then in the results is the memberships (enrollments). Each user membership returns the user info and can be consumed to relayed to end user/application. This will save on several calls down the road. Now let's say you wish to filter the results of this data: ?populate=true&filters={populated: {course: <filters-here>, results: <filters-here>}}.

     

    Now this can have several interpretations as to how the filters can be applied:

     

    filters: base json object to setup how to determine which data sets to apply to

    course: maybe called: base, main, or reference, etc. Something to let the user or application know if the main data set reference

    results: filter the end results on actual result or, pass in a set of filters to the referencing populated data. For instance, maybe one does not wish to see all the fields returned for the referenced record.

     

    so maybe: filters={populated: {course: 'externalId,id,availability', users: 'externalId,id,userName,contact,name'}}

     

    Proposed result:

     

    {
      "course": {
        "id": "_2841_1",
        "externalId": "LOR-CC-mbechtel",
        "availability": {
          "available": "Yes",
          "duration": {
            "type": "Continuous"
          }
        }
      }, 
      results:
      [{
        "user": {
          "id": "_43_1",
          "externalId": "73099",
          "userName": "mbechtel",
          "contact": {
            "email": "mbechtel@irsc.edu"
          },
          "name": {
            "given": "Michael",
            "family": "Bechtel",
            "title": "System Admin"
          }
        },
        "dataSource": '_2_1',
        "created": '2016-10-05T14:56:25.000Z',
        "availability": {
          "available": "Yes"
        },
        "courseRoleId": 'Instructor'
      },
        ....
     ] }
    

    The "course" key could also be abstracted to just "base", "target", or whatever main reference convention that will allow the user/application use to keep track of the main reference.

    Product Version (if applicable):