Skip to content

Commit 66cf420

Browse files
committed
officially support JSON PUT and POST requests in the API
This already worked and was used by the Canvas front-end internally, but wasn't officially supported. test plan: make an API POST or PUT, and send an application/json body rather than an application/x-www-form-urlencoded request body. Change-Id: I2ecf2dce8ed8a592a101b6566c0b483737a68702 Reviewed-on: https://gerrit.instructure.com/10930 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Zach Pendleton <zachp@instructure.com>
1 parent 3e1fdda commit 66cf420

2 files changed

Lines changed: 62 additions & 1 deletion

File tree

doc/api/README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,17 @@ For POST and PUT requests, parameters are sent using standard
1919
<a href="http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4">HTML form
2020
encoding</a> (the application/x-www-form-urlencoded content type).
2121

22-
All timestamps are sent and returned in ISO 8601 format (UTC time zone):
22+
POST and PUT requests may also optionally be sent in <a href="http://www.json.org/">JSON format</a> format. The content-type of the request must be set to application/json in this case. There is currently no way to upload a file as part of a JSON POST, the multipart form type must be used.
23+
24+
As an example, this HTML form request:
25+
26+
name=test+name&file_ids[]=1&file_ids[]=2&sub[name]=foo&sub[message]=bar
27+
28+
would translate into this JSON request:
29+
30+
{ "name": "test name", "file_ids": [1,2], "sub": { "name": "foo", "message": "bar" } }
31+
32+
With either encoding, all timestamps are sent and returned in ISO 8601 format (UTC time zone):
2333

2434
YYYY-MM-DDTHH:MM:SSZ
2535

spec/apis/general_api_spec.rb

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,55 @@ def @course.filter_attributes_for_user(hash, user, session)
5252
@course.as_json(:include_root => false, :permissions => { :user => @user, :include_permissions => false }, :only => %w(name sis_source_id)).keys.sort.should == %w(name sis_source_id)
5353
end
5454
end
55+
56+
describe "json post format" do
57+
before do
58+
course_with_teacher(:user => user_with_pseudonym, :active_all => true)
59+
@token = @user.access_tokens.create!(:purpose => "specs")
60+
end
61+
62+
it "should use html form encoding by default" do
63+
html_request = "assignment[name]=test+assignment&assignment[points_possible]=15"
64+
# no content-type header is sent
65+
post "/api/v1/courses/#{@course.id}/assignments", html_request, { "authorization" => "Bearer #{@token.token}" }
66+
response.should be_success
67+
response.header['content-type'].should == 'application/json; charset=utf-8'
68+
69+
@assignment = @course.assignments.last(:order => :id)
70+
@assignment.title.should == "test assignment"
71+
@assignment.points_possible.should == 15
72+
end
73+
74+
it "should support json POST request bodies" do
75+
json_request = { "assignment" => { "name" => "test assignment", "points_possible" => 15 } }
76+
post "/api/v1/courses/#{@course.id}/assignments", json_request.to_json, { "content-type" => "application/json", "authorization" => "Bearer #{@token.token}" }
77+
response.should be_success
78+
response.header['content-type'].should == 'application/json; charset=utf-8'
79+
80+
@assignment = @course.assignments.last(:order => :id)
81+
@assignment.title.should == "test assignment"
82+
@assignment.points_possible.should == 15
83+
end
84+
85+
it "should use array params without the [] on the key" do
86+
assignment_model(:course => @course, :submission_types => 'online_upload')
87+
@user = user_with_pseudonym
88+
course_with_student(:course => @course, :user => @user, :active_all => true)
89+
@token = @user.access_tokens.create!(:purpose => "specs")
90+
a1 = attachment_model(:context => @user)
91+
a2 = attachment_model(:context => @user)
92+
json_request = { "comment" => {
93+
"text_comment" => "yay" },
94+
"submission" => {
95+
"submission_type" => "online_upload",
96+
"file_ids" => [a1.id, a2.id] } }
97+
post "/api/v1/courses/#{@course.id}/assignments/#{@assignment.id}/submissions", json_request.to_json, { "content-type" => "application/json", "authorization" => "Bearer #{@token.token}" }
98+
response.should be_success
99+
response.header['content-type'].should == 'application/json; charset=utf-8'
100+
101+
@submission = @assignment.submissions.find_by_user_id(@user.id)
102+
@submission.attachments.map { |a| a.id }.sort.should == [a1.id, a2.id]
103+
@submission.submission_comments.first.comment.should == "yay"
104+
end
105+
end
55106
end

0 commit comments

Comments
 (0)