Inline fragments

GraphQL's permits polymorphism through inline fragments, through objects being available as GraphQL Unions and Interfaces. Eduflow uses inline fragments across the various activity object types.

Eduflow activities all have Activity.title, so all activities inherit from ActivityInterface.

Querying

Query
Response
Query
{
course(id: "00000000-5945-95c7-65fc-a9747b200320") {
flows {
activities {
... on ActivityInterface {
title
}
}
}
}
}
Response
{
"data": {
"course": {
"flows": [
{
"activities": [
{
"title": "Welcome to the root-level Activity"
}
]
},
{
"activities": [
{
"title": "Learn about paper"
},
{
"title": "Environmental friendliness"
},
{
"title": "Climate change"
}
]
},
{
"activities": [
{
"title": "Introduction to sales"
},
{
"title": "CRM technology"
},
{
"title": "Funnel configuration"
}
]
}
]
}
}
}

Inline fragments

Using specific activity fragments act as a way to upcast objects. Here's an example of PeerReview ran against the connection above, and via direct activity lookup.

Query (Connection)
Response
Query (Direct lookup)
Response
Query (Connection)
{
course(id: "00000000-5945-95c6-65fc-a9747b200320") {
flows {
activities {
__typename
... on ActivityInterface {
title
}
... on PeerReviewActivity {
reviews {
edges {
node {
reviewType
createdAt
}
}
}
}
}
}
}
}
Response

Notice the specialized fields only return for the activity type that are PeerReviews:

{
"data": {
"course": {
"flows": [
{
"activities": [
{
"__typename": "ContentActivity",
"title": "Welcome aboard!"
}
]
},
{
"activities": [
{
"__typename": "ContentActivity",
"title": "Our Mission"
},
{
"__typename": "SubmissionActivity",
"title": "Make an impact"
},
{
"__typename": "PeerReviewActivity",
"title": "Spot-check and team build",
"reviews": {
"edges": [
{
"node": {
"reviewType": "PeerReview",
"createdAt": "2021-02-08T17:56:30.576582"
}
},
{
"node": {
"reviewType": "PeerReview",
"createdAt": "2021-02-08T17:56:30.617394"
}
},
{
"node": {
"reviewType": "PeerReview",
"createdAt": "2021-02-08T17:56:30.661450"
}
},
{
"node": {
"reviewType": "PeerReview",
"createdAt": "2021-02-08T17:56:30.703841"
}
},
{
"node": {
"reviewType": "PeerReview",
"createdAt": "2021-02-08T17:56:32.501897"
}
}
]
}
},
{
"__typename": "FeedbackReflectionActivity",
"title": "Introspect and reflect"
},
{
"__typename": "TeacherReviewActivity",
"title": "From your manager"
},
{
"__typename": "SelfReviewActivity",
"title": "How would you improve?"
},
{
"__typename": "ContentActivity",
"title": "Water cooler"
},
{
"__typename": "ContentActivity",
"title": "Networking: Meet across divisions"
}
]
},
{
"activities": [
{
"__typename": "ContentActivity",
"title": "Paper: Relevant today?"
},
{
"__typename": "SubmissionActivity",
"title": "How do you use paper?"
},
{
"__typename": "ContentActivity",
"title": "Our philosophy"
}
]
}
]
}
}
}
Query (Direct lookup)

title exists in PeerReviewActivity as well, no need to use ActivityInterface:

{
activity(id: "10aa7684-f0b2-4595-9161-4845e3602312") {
... on PeerReviewActivity {
title
reviews {
edges {
node {
reviewType
createdAt
}
}
}
}
}
}
title exists on PeerReviewActivity, as it inherits from ActivityInterface
Response
{
"data": {
"activity": {
"title": "Spot-check and team build",
"reviews": {
"edges": [
{
"node": {
"reviewType": "PeerReview",
"createdAt": "2021-02-08T17:56:30.576582"
}
},
{
"node": {
"reviewType": "PeerReview",
"createdAt": "2021-02-08T17:56:30.617394"
}
},
{
"node": {
"reviewType": "PeerReview",
"createdAt": "2021-02-08T17:56:30.661450"
}
},
{
"node": {
"reviewType": "PeerReview",
"createdAt": "2021-02-08T17:56:30.703841"
}
},
{
"node": {
"reviewType": "PeerReview",
"createdAt": "2021-02-08T17:56:32.501897"
}
}
]
}
}
}
}

See also