Bug when updating quizzes?
I kinda figured that the output of the GET version would be valid in the PUT but according to the documentation it looks like the 2 formats are ever so slightly different.
Now I looked over my request body dozens of time and I cannot for the life of me figure out why the API is returning
{"type":"http://docs.valence.desire2learn.com/res/apiprop.html#json-binding-error","title":"JSON Binding Error","status":400,"detail":"Provided JSON is invalid or does not match the expected format."}
If anyone can figure out what about my payload is wrong (or if the API has a bug) that's be greatly appreciated.
gist to my payload:
https://gist.github.com/hydroflame/f63a32d513365a6b567ba2addbb34a75
It is worth nothing that I first get the quiz from /quizzes/quizId and then apply the following transformation in order to try and match what the d2l documentation says about the body of a PUT request for updating quizzes:
- delete QuizId (does not appear in the documentation)
- delete AttemptsAllowed (same)
- delete ActivityId (same)
- set NumberOfAttemptsAllowed to old.AttemptsAllowed.NumberOfAttemptsAllowed (the documentation refers to that information differently between the GET response and PUT body)
- set Password to "" (It's null from the GET and the PUT body documentation specifically says the password cannot be null, but also says it cannot be an empty string. null or empty string it doesn't work)
- set NotificationEmail to "" (It's null from the GET and the PUT body documentation says it must be a string)
- set RestrictIPAddressRange to [] (It comes back as an empty array so I figured I'd try something.)
The only information I'm trying to change is the start/due/end date. Everything else is the same.
Can anybody spot my mistake?
Answers
-
The error you're encountering,
"Provided JSON is invalid or does not match the expected format,"
suggests there is a mismatch between the structure or content of your JSON payload and what the API endpoint expects. Here are a few suggestions and things to check based on the transformations you're applying and the issue you're facing:- Field Deletion:
- You mentioned deleting
QuizId
,AttemptsAllowed
, andActivityId
as they do not appear in the PUT request documentation. Ensure these fields are indeed not required by the PUT endpoint. Sometimes, documentation might omit certain fields, assuming they are understood to be required or optional based on context or convention.
- You mentioned deleting
- Attempts Allowed:
- You are transforming
old.AttemptsAllowed.NumberOfAttemptsAllowed
toNumberOfAttemptsAllowed
. Double-check if the API expectsNumberOfAttemptsAllowed
directly or if it should be nested inside another object or structure.
- You are transforming
- Password Field:
- The API specifies that the password cannot be
null
and cannot be an empty string. This is a bit contradictory since these are usually the two ways to represent "no password." You might want to try sending a dummy password, like a space" "
or some random string, and see if that is accepted. If it works, it might not be the ideal solution, but it can be a temporary workaround until you get clarification on this behavior.
- The API specifies that the password cannot be
- NotificationEmail Field:
- Similar to the password, if the documentation says it must be a string and cannot be
null
, setting it to an empty string""
is generally the right approach. However, if this doesn't work, you might consider putting in a dummy email or your own email to test if it accepts that.
- Similar to the password, if the documentation says it must be a string and cannot be
- RestrictIPAddressRange:
- Setting
RestrictIPAddressRange
to an empty array[]
seems correct if the API documentation doesn't specify otherwise. Ensure that this field is indeed expected to be an array and that having an empty array is valid.
- Setting
- Date Fields:
- Since you're trying to change start/due/end dates, make sure the format of the dates matches exactly what the API expects. Date format issues are a common source of API errors. The required format can sometimes be ISO 8601 or another specific format.
- Validation Against Schema:
- If you have access to the JSON schema or a precise documentation of the expected structure, validate your JSON against that schema. There are online tools available for JSON validation against a schema, which can help pinpoint structural issues.
- Check for Unintended Null Values:
- Ensure that your transformation process isn't introducing
null
values or removing necessary fields unintentionally.
- Ensure that your transformation process isn't introducing
- API Version and Endpoint Consistency:
- Ensure that you're hitting the correct version of the API. Sometimes, APIs have versioned paths, and behavior can differ significantly between versions.
- Contact API Support:
- If you've double-checked everything and it still doesn't work, consider reaching out to the API support team. Sometimes the issue might be on the backend, or the documentation might be outdated or missing crucial information.
In debugging such issues, it can also be helpful to use tools like Postman or Curl to manually craft requests. This way, you can isolate the problem away from your code logic and transformations.
- Field Deletion:
-
How do I contact the API support team?
-
Follow up on
How can I contact the API team?
-
@Olivier.G.532
I'm connecting with some of our API SMEs here at D2L to provide you an update. -
This seems like it could be a fairly classic gotcha with the Brightspace APIs.
With a lot of the APIs, when you read an entity from Brightspace user-visible-text fields get encoded as RichText structures. However, when you write to create or update that entity into Brightspace, often you need to encode those fields as RichTextInput structures. The particular Quiz API structures here use that pattern, I believe (QuizReadData for read, QuizData for write).
You may find that making this adjustment to your call addresses the issue. -
@Viktor.H.147 Ah yes you found it. That is a gotcha. Can we log a couple bugs though? Like e.g. the API says that Quiz password cannot be null but it can and it indicated no password.
Thanks you for your help. I was able to finish my tool
(no I can't get an approved app from Algonquin College so I have to do the token shenanigan) -
If you post the documentation inconsistencies here, I can see that they're followed up on. If the real cause of the inconsistency turns out to be an implementation problem, we'll likely need a support case; but if the error is on the documentation end of things, we can get that done without the effort of a support case.
-
NotificationEmail Password
Both of these fields from
QuizData
are marked as required string in the documentation despite the API acceptingnull
for various reasons.QuizReadData
also says they cannot benull
but will sometimes come back as such.Additionally
QuizReadData
saysRestrictedIPRange
will not benull
but it can.It's also confusing that
POST /folders/{folderId}
acceptsRichText
without transformation from theGET
endpoint, which is why I initially didn't transform it for quizzes. But I guess that's nice? So if quizzes could also acceptRichText
that's be cool. -
Yes, sadly the pattern of "RichText on read, RichTextInput on input" is not entirely consistent. Thanks for your report!