In a series of posts, we have seen how to implement User Defined Functions.
Let’s move on to our next topic : Triggers
We should use trigger to
- Maintain integrity of data
- Automate a response to an event
- Do a validation check
In Hypi, @trigger
is a directive supported with before
and after
semantics.
Quoting from the documentation some important points:
- A trigger’s before function is executed synchronously. i.e. it will complete before the function it is attached to.
- A trigger’s after function is executed asynchronously. i.e. the function it is attached to will return before the trigger is completed.
- If a trigger’s before function returns false, the function it is attached to will not be executed, nor will the after function.
Example
Suppose we have a Student Database and we need to update the marks of the student for various subjects.
While updating the student record we will do a validation check if the record exists. That will be our before
function.
After the record gets updated successfully, we will formulate a notification message. The notification can also be sent over to notification services. Here we have just stored the message in a data type for simplicity. This will be our after
function.
Here is the schema!
type UpdateNotification {
id : ID
updateDate : DateTime
message: String
}
type StudentInformation {
name : String
dob: DateTime
address: Address
standard: String
division: String
contact: Int
marks: StudentMarks
}
type Query{
checkID(sub1:Float,sub2:Float,sub3:Float, hypiId: ID):Boolean @tan(type:Groovy,
inline: """
def id = gql(\"""{get(type:StudentInformation,id:"$hypiId"){...on StudentInformation{hypi{id}}}}\""").data.get.hypi.id
if (id=="$hypiId") {
return true
} else {
return false
}
""")
}
type Mutation {
# Trigger Function
addStudentMarks(sub1:Float,sub2:Float,sub3:Float, hypiId: ID):Json @tan(type:Groovy,
inline: """
return gql(\"""
mutation {
upsert(
values: {
StudentInformation: [
{
hypi: {id: "$hypiId"},
marks: { subject1: $sub1, subject2: $sub2, subject3: $sub3 }
}
]
}
) {
id
}
}
\"""
)
""") @trigger(config: {
before: {type: Query, field: "checkID"},
after: {type: Mutation, field: "formNotification"}
})
formNotification(sub1:Float,sub2:Float,sub3:Float, hypiId: ID):Boolean @tan(type:Groovy,
inline: """
def date = gql(\"""{get(type:StudentInformation,id:"$hypiId"){...on StudentInformation{hypi{updated}}}}\""").data.get.hypi.updated
def msg = "The student record with id : '$hypiId' updated"
gql(\"""
mutation {
upsert(
values: {
UpdateNotification: [
{
id:"$hypiId",
updateDate:"$date",
message: "$msg"
}
]
}
) {
id
}
}
\""")
return true
""")
}
-
checkID
is thebefore
function that checks if the provided input hypi ID is correct. -
addStudentMarks
function updates the student record. -
formNotification
forms the message for notification. You may actually send the notification through http gateway by Hypi or through serverless function. - We are updating already created
StudentInformation
object or record. Hence using hypi.id to update the record.
Let’s execute the function!
mutation{
addStudentMarks(sub1:10.0,sub2:10.0,sub3:10.0,hypiId:"01FHA2NZRQK7M2SABRRNZ7E65X")
}
#result
{
"data": {
"addStudentMarks": null
},
"errors": [
{
"message": "Exception while fetching data (/addStudentMarks) : io.hypi.arc.os.gql.HypiGraphQLException: Pre-condition given by Query.checkID failed",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"addStudentMarks"
]
}
]
}
before
function fails if the record doesn’t exist.
mutation{
addStudentMarks(sub1:10.0,sub2:10.0,sub3:10.0,hypiId:"01FSA2NZRQK7M2SABRRNZ7E65X")
}
#result
{
"data": {
"addStudentData": [
{
"__typename": "Hypi",
"id": "01FSA2NZRQK7M2SABRRNZ7E65X",
"impl": null,
"created": "2022-01-13T16:00:11Z",
"updated": "2022-01-13T16:00:11Z",
"trashed": null,
"createdBy": "01FQDY5XDRQPERKPCWAWYDFV7W",
"instanceId": "01FQDYDP8681299EXZBWJXRX2Y",
"tags": null
}
]
}
}
#UpdateNotification Data
{
"data": {
"find": {
"edges": [
{
"node": {
"hypi": {
"id": "01FSA3EDXADX1XC48EKWG9098N"
},
"id": "01FSA2NZRQK7M2SABRRNZ7E65X",
"updateDate": "2022-01-13T16:13:31Z",
"message": "The student record with id : '01FSA2NZRQK7M2SABRRNZ7E65X' updated"
},
"cursor": "01FSA3EDXADX1XC48EKWG9098N"
}
]
}
}
}