cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
CaseyV
Community Member

How to Query All Users with GraphQL

I am extremely new to the world of graphql (it's my weekend project to start learning it). I was poking around the API and found the /graphiql route in my canvas instance.

With the REST API, I can easily query all users in my instance. Unfortunately, I can't find a way to do this (yet) with the graphql API. If someone could assist with this query it would be a huge help and a great example for me to work off of this weekend as I study. Thanks!

0 Kudos
4 Replies
paul14
Community Participant

Hi Casey,

How are you going with your GraphQL journey?

I don't have anything to offer to answer your question but just curious to see how you're going with it all. Just starting out myself.

I noticed with the https://[ourinstitute].instructure.com/graphiql interface I can get some pretty deep data and the challenge seems to be reigning it in to not pull in too much stuff.

James
Community Champion

Not all information is available through GraphQL.

There is no usersConnection under account, but there is under account.coursesConnection. That means that you can get the list of all of the users for a course and do this for all courses within an account, but this is going to be a duplicated list. You can filter on a particular enrollment state for a user, but you cannot filter on types of courses (to just get those that are active).

Here is a GraphQL command that will list the active users for the first 10 courses. Be sure to change the id for the account to match yours. 

query listUsers {
  account(id: "12345") {
    coursesConnection(first: 10) {
      nodes {
        usersConnection(filter: {enrollmentStates: active}) {
          nodes {
            _id
            name
            sortableName
            email
            sisId
          }
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
}

If you don't want to filter by enrollment state, then change the usersConnection line to be

usersConnection {

In the response, you will get some pageInfo. If hasNextPage is true, then use the endCursor to make the next call.

My endCursor after that call above was "MTA" so my second call would modify the coursesConnection line to look like this:

coursesConnection(first: 10, after: "MTA") {

The pagination becomes important when you have a lot of courses or a lot of students. For small queries, GraphQL can return results, but it times out after about 30 seconds. This means that you may need to request fewer courses or even restrict the number of users in a course. If you use a first with the usersConnection, then it limits the number of users returned per course, which can be confusing and you would need to return the pageInfo for the usersConnection if you wanted to get all of the users in that course.

 

On the other hand, using the REST API, you can get an unduplicated list of users within an account with the List users in account endpoint. You will still need to handle pagination as you won't be able to retrieve more than 100 users at a time. 

jerry_nguyen
Community Participant

@CaseyV 

As James mentioned, not all information is available through GraphQL as it's still in development. The ability to filter data is very limited. 

If you decided to use GraphQL, it's likely that you will need to combine it with the traditional REST API to get the data that you needed. 

However, in some cases, using GraphQL can reduce the number of REST API calls

For example, you can get the list of user's id from REST API then combine it with the following GraphQL query to get a student's submissions in each course 

 

 

  legacyNode(_id: "12345", type: User) {
    ... on User {
      id
      email
      enrollments {
        course {
          name
          assignmentsConnection {
            nodes {
              submissionsConnection {
                nodes {
                  id
                  submissionStatus
                  state
                  grade
                }
              }
              name
            }
          }
        }
      }
    }
  }
}

 

 

I use "legacyNode" in the above example. legacyNode attempts to replicate REST API endpoints. However, again, not all information is available. 

paul14
Community Participant

James you provide such detailed, thoughtful and helpful replies here it's awesome.

Thank you also Jerry!