Celebrate Excellence in Education: Nominate Outstanding Educators by April 15!
Found this content helpful? Log in or sign up to leave a like!
While reviewing our Feature Options today, I was excited to notice for the first time one called "GraphQL API." It's marked beta and described as "EXPERIMENTAL GraphQL API."
I know about GraphQL but couldn't find any info at all on its use in Canvas. Has anyone heard anything about this? Thanks!
Solved! Go to Solution.
Hi --
I finally had some time to update our local Canvas instance with the latest code from GitHub and I've spent a little time poking at the graphql API. First, there's a browser-based graphql console (GraphiQL) that is installed along with Canvas, but seems to only be available to users with administrator privileges on the "Site Admin" account (we have access to this in our locally-hosted development instance of Canvas, but not in our Instructure-hosted instances). The actual graphql API endpoint (/api/graphql) is accessible by regular users in our local instance.
Here's an example of a query that I managed to get to work, sent as the body of a POST request to /api/graphql:
{"query": "
{
allCourses {
id,
name,
courseCode,
state
}
}
"}
That returns a data structure with information about the courses that are on the user's dashboard. Still trying to figure out how to drill down into sections, etc...
--Colin
Thanks for getting would out that Instructure may be taking steps toward supporting a GraphQL api. I had heard about GraphQL in a talk by David Nolan, and I recognized that it could be a benefit for some of the complex queries we need to do that span over multiple endpoints. Like you I would like to find out more about how Canvas is implementing it.
MIke
Funny coincidence - I just asked our CSR about that last week - I'll update if she's able to get any info.
BTW, you can get some clues regarding how they're using graphql here: Search · org:instructure graphql · GitHub
Hey Daniel!
I'm also very interested in the GraphQL API -- I've seen a bunch of related GitHub commits and I've been meaning to make some time to experiment with it. I'm expecting to have to read some source code to figure out how to use it 🙂
BTW -- we did learn that there's some (fairly edge-case) bug that causes problems rendering student context cards in unpublished courses and/or with inactive students when the GraphQL feature flag is turned on. It seems that Instructure engineering is aware of it, and I imagine it'll be fixed soon, but we've disabled that flag in production for now.
If I do get it working, I'll share my notes here!
--Colin
Great, thanks, Colin!
Looking forward to hearing about your experiments.
After reading your post I found the experiment graphql api setting
What happens if you turn it on?
Is it an api that I can use or is it an api that canvas uses internally.
I'm interested in what I imagine is the potential here, but I know so little about the implementation that it's dangerous
Is there any schemer or endpoint documentation?
Hi --
I finally had some time to update our local Canvas instance with the latest code from GitHub and I've spent a little time poking at the graphql API. First, there's a browser-based graphql console (GraphiQL) that is installed along with Canvas, but seems to only be available to users with administrator privileges on the "Site Admin" account (we have access to this in our locally-hosted development instance of Canvas, but not in our Instructure-hosted instances). The actual graphql API endpoint (/api/graphql) is accessible by regular users in our local instance.
Here's an example of a query that I managed to get to work, sent as the body of a POST request to /api/graphql:
{"query": "
{
allCourses {
id,
name,
courseCode,
state
}
}
"}
That returns a data structure with information about the courses that are on the user's dashboard. Still trying to figure out how to drill down into sections, etc...
--Colin
That's really interesting - I had been thinking about graphql as a being an admin tool, i.e. being able to write a generic query for a user's courses or whatever, but it seems like it's limited to retrieving info for the specific user that is authenticated against it (unlike how the rest api will let an admin user query all courses, users, etc)
For people that want to poke with a command line, here's a quick recipe (using bash & jq)
bash is easy enough to get going with - set up an alias (replace `generate~your~token` & `yourCanvasServerName` natch):
gqltoken=[generate~your~token]
instance=https://yourCanvasServerName.instructure.com
alias cgql="curl -H \"Authorization: Bearer $gqltoken\" -X POST $instance/api/graphql -H \"Content-Type: application/json\""
then here's Colin's example as a one-liner piped to jq for easy readability (note: subbing _id for id will give you the canvas id of the courses)
cgql -d "{\"query\": \"{ allCourses {_id,name,courseCode,state}}\"}" | jq
you can help your explorations a bit using graphql introspection to get a list of types:
cgql -d "{\"query\": \" { __schema {types{name}}} \"}" | jq '.data.__schema.types | .[] | .name'
You can get information on a single course using legacyNode(type:Course,_id: xxx):
{
legacyNode(type: Course, _id: 20512) {
... on Course {
_id
name
}}}
Here's how to get some course information:
Enrollments is userConnection > edges > node > fieldnames
{
legacyNode(type: Course, _id: 20512) {
... on Course {
_id
name
usersConnection {
edges {
node {
name
_id
email
}}}}}}
or as a one-liner (well, a two-liner so the variable is replaceable)
course_id=20512
cgql -d "{\"query\": \" {legacyNode(type:Course,_id:$course_id){... on Course{_id name usersConnection{edges{node{name _id email}}}}}} \"}"
Sections are similar:
{
legacyNode(type: Course, _id: 20512) {
... on Course {
_id
name
sectionsConnection {
edges {
node {
name
_id
createdAt
updatedAt
}}}}}}
or
course_id=20512
cgql -d "{\"query\": \" {legacyNode(type:Course,_id:$course_id){... on Course{_id name sectionsConnection{edges{node{name _id createdAt updatedAt}}}}}} \"}" | jq
Pretty much all of the xConnection types seem to follow that basic pattern and you can end up getting pretty specific results putting it all together - here's an example that get's a single course via it's course id and get's the current user's permissions, plus the course users with grades and analytics :
{
legacyNode(type: Course, _id: 20512) {
... on Course {
_id
name
permissions {
become_user: becomeUser
manage_grades: manageGrades
send_messages: sendMessages
view_all_grades: viewAllGrades
view_analytics: viewAnalytics
}
usersConnection {
edges {
node {
name
email
analytics: summaryAnalytics(courseId: 20512) {
page_views: pageViews {
total
max
level
}
participations {
total
max
level
}
tardiness_breakdown: tardinessBreakdown {
late
missing
on_time: onTime
}
}
enrollments(courseId: 20512) {
last_activity_at: lastActivityAt
section {
name
}
grades {
current_grade: currentGrade
current_score: currentScore
}
}
}
}
}
}
}
}
Sample Output (side note - I'm am still thrilled when emoji don't break apis):
{
"data": {
"legacyNode": {
"_id": "20512",
"name": " Dank Memes and Dark Dreams",
"permissions": {
"become_user": true,
"manage_grades": true,
"send_messages": true,
"view_all_grades": true,
"view_analytics": true
},
"usersConnection": {
"edges": [
{
"node": {
"name": "Test Student",
"email": null,
"analytics": {
"page_views": {
"total": 3,
"max": 67,
"level": 2
},
"participations": {
"total": 0,
"max": 0,
"level": 0
},
"tardiness_breakdown": {
"late": 0,
"missing": 0,
"on_time": 2
}
},
"enrollments": [
{
"last_activity_at": "2017-05-02T15:14:46-04:00",
"section": {
"name": "Dank Memes ⚙♻️ "
},
"grades": {
"current_grade": null,
"current_score": 63.5
}
}
]
}
}
]
}
}
}
}
Peter --
This is great! Lots of useful information -- thanks for sharing.
And yeah -- I'd hoped it'd be more of a general-purpose API that we could use in custom tools, reporting, etc. We'll see what Instructure does with it going forward!
--Colin
Thank you this was very helpful. looking in to the introspection system I made this query.
It returns a list of all the queries available and the augments they take.
{ __type(name:"Query") {
fields {
name
args{name,defaultValue,description}
}
}
}
This is what it returned today.
{
"data": {
"__type": {
"fields": [
{
"name": "allCourses",
"args": []
},
{
"name": "legacyNode",
"args": [
{
"name": "_id",
"defaultValue": null,
"description": null
},
{
"name": "type",
"defaultValue": null,
"description": null
}
]
},
{
"name": "node",
"args": [
{
"name": "id",
"defaultValue": null,
"description": "ID of the object."
}
]
}
]
}
}
}
There are currently three queries, allCourses, legacyNode, and node. You can also see their arguments.
I also found their schema and type definitions for their graphql in their source code.
That helped too.
Hope this helps the next guy!
@phanley using the non-legacy nodes you can get users in the course with:
{ course(id: "2") { id _id name state } node(id: "Q291cnNlLTI=") { id ... on Course { id name usersConnection { edges { node { id email name } } } } } }
If anyone noticed that the ability to turn it on disappeared from their beta instance, it looks like it's been turned on for everyone.... and that it'll be in production possibly soon
enable graphql feature flag · instructure/canvas-lms@c35e13f · GitHub
Test plan: * make sure graphql is turned on for accounts that previously had graphql enabled and then disabled * make sure graphql can't be turned off
I am glad someone finally asked that question. I have see it a few times and never really followed up on it.
Should be visible in production
/graphiql
not the i
you must be authenticated
the docs apparently have an issue that will be updated in a couple of release cycles
https://github.com/instructure/canvas-lms/blob/stable/schema.graphql
I spoke to someone at CanvasCon in Sydney about graphql.
The impetus is the mobile app.
Once it is functional it will/may be merged into the canvas codebase.
Hello,
am exploring GraphQL for retrieving students data in New Analytics feature and when I inspect XHR request in the browser I see Query (ChartQuery) as below but Canvas production URL (e.g. your-institution.instructure.com/graphiql) doesn't have studentInCourseConnection node .
Error:
please suggest if am missing something here.
Query:
query ChartQuery($contextId: String!, $tcGuid: String!, $startDate: ServerDateTime, $endDate: ServerDateTime) {
course(contextId: $contextId, tcGuid: $tcGuid) {
studentCount
sections {
id
name
__typename
}
studentInCourseConnection {
edges {
sections {
id
name
__typename
}
__typename
}
__typename
}
weeklyPageviewCounts(startDate: $startDate, endDate: $endDate) {
startDate
count
incomplete
__typename
}
weeklyParticipationCounts(startDate: $startDate, endDate: $endDate) {
startDate
count
incomplete
__typename
}
__typename
}
}
Analytics screen in Canvas:
To participate in the Instructure Community, you need to sign up or log in:
Sign In