Return API pagination links as headers rather than in the response body itself

This commit is contained in:
Jonne Haß 2019-04-28 15:44:30 +02:00 committed by Jonne Haß
parent 2f7acbe4b3
commit dad54db7f4
26 changed files with 46 additions and 53 deletions

View file

@ -15,7 +15,7 @@ module Api
aspects_query = current_user.aspects aspects_query = current_user.aspects
aspects_page = index_pager(aspects_query).response aspects_page = index_pager(aspects_query).response
aspects_page[:data] = aspects_page[:data].map {|a| aspect_as_json(a, false) } aspects_page[:data] = aspects_page[:data].map {|a| aspect_as_json(a, false) }
render json: aspects_page render_paged_api_response aspects_page
end end
def show def show

View file

@ -49,6 +49,15 @@ module Api
Api::Paging::RestPaginatorBuilder.new(query, request).index_pager(params) Api::Paging::RestPaginatorBuilder.new(query, request).index_pager(params)
end end
def render_paged_api_response(page)
link_header = []
link_header << %(<#{page[:links][:next]}>; rel="next") if page[:links][:next]
link_header << %(<#{page[:links][:previous]}>; rel="previous") if page[:links][:previous]
response.set_header("Link", link_header.join(", ")) if link_header.present?
render json: page[:data]
end
def time_pager(query) def time_pager(query)
Api::Paging::RestPaginatorBuilder.new(query, request).time_pager(params) Api::Paging::RestPaginatorBuilder.new(query, request).time_pager(params)
end end

View file

@ -35,7 +35,7 @@ module Api
comments_page = time_pager(comments_query).response comments_page = time_pager(comments_query).response
comments_page[:data] = comments_page[:data].map {|x| comment_as_json(x) } comments_page[:data] = comments_page[:data].map {|x| comment_as_json(x) }
render json: comments_page render_paged_api_response comments_page
end end
def destroy def destroy

View file

@ -23,7 +23,7 @@ module Api
contacts_page[:data] = contacts_page[:data].map do |c| contacts_page[:data] = contacts_page[:data].map do |c|
ContactPresenter.new(c, current_user).as_api_json_without_contact ContactPresenter.new(c, current_user).as_api_json_without_contact
end end
render json: contacts_page render_paged_api_response contacts_page
end end
def create def create

View file

@ -22,7 +22,7 @@ module Api
conversations_query = conversation_service.all_for_user(mapped_params) conversations_query = conversation_service.all_for_user(mapped_params)
conversations_page = pager(conversations_query, "conversations.created_at").response conversations_page = pager(conversations_query, "conversations.created_at").response
conversations_page[:data] = conversations_page[:data].map {|x| conversation_as_json(x) } conversations_page[:data] = conversations_page[:data].map {|x| conversation_as_json(x) }
render json: conversations_page render_paged_api_response conversations_page
end end
def show def show

View file

@ -26,7 +26,7 @@ module Api
likes_query = like_service.find_for_post(params[:post_id]) likes_query = like_service.find_for_post(params[:post_id])
likes_page = index_pager(likes_query).response likes_page = index_pager(likes_query).response
likes_page[:data] = likes_page[:data].map {|x| like_json(x) } likes_page[:data] = likes_page[:data].map {|x| like_json(x) }
render json: likes_page render_paged_api_response likes_page
end end
def create def create

View file

@ -27,7 +27,7 @@ module Api
conversation.set_read(current_user) conversation.set_read(current_user)
messages_page = index_pager(conversation.messages).response messages_page = index_pager(conversation.messages).response
messages_page[:data] = messages_page[:data].map {|x| message_json(x) } messages_page[:data] = messages_page[:data].map {|x| message_json(x) }
render json: messages_page render_paged_api_response messages_page
end end
private private

View file

@ -29,7 +29,7 @@ module Api
notifications_page[:data] = notifications_page[:data].map do |note| notifications_page[:data] = notifications_page[:data].map do |note|
NotificationPresenter.new(note, default_serializer_options).as_api_json NotificationPresenter.new(note, default_serializer_options).as_api_json
end end
render json: notifications_page render_paged_api_response notifications_page
rescue ArgumentError rescue ArgumentError
render json: I18n.t("api.endpoint_errors.notifications.cant_process"), status: :unprocessable_entity render json: I18n.t("api.endpoint_errors.notifications.cant_process"), status: :unprocessable_entity
end end

View file

@ -23,7 +23,7 @@ module Api
end end
photos_page = time_pager(query).response photos_page = time_pager(query).response
photos_page[:data] = photos_page[:data].map {|photo| photo_json(photo) } photos_page[:data] = photos_page[:data].map {|photo| photo_json(photo) }
render json: photos_page render_paged_api_response photos_page
end end
def show def show

View file

@ -28,7 +28,7 @@ module Api
author: PersonPresenter.new(r.author).as_api_json author: PersonPresenter.new(r.author).as_api_json
} }
end end
render json: reshares_page render_paged_api_response reshares_page
end end
def create def create

View file

@ -14,13 +14,13 @@ module Api
def user_index def user_index
user_page = index_pager(people_query).response user_page = index_pager(people_query).response
user_page[:data] = user_page[:data].map {|p| PersonPresenter.new(p).as_api_json } user_page[:data] = user_page[:data].map {|p| PersonPresenter.new(p).as_api_json }
render json: user_page render_paged_api_response user_page
end end
def post_index def post_index
posts_page = time_pager(posts_query, "posts.created_at", "created_at").response posts_page = time_pager(posts_query, "posts.created_at", "created_at").response
posts_page[:data] = posts_page[:data].map {|post| PostPresenter.new(post).as_api_response } posts_page[:data] = posts_page[:data].map {|post| PostPresenter.new(post).as_api_response }
render json: posts_page render_paged_api_response posts_page
end end
private private

View file

@ -54,7 +54,7 @@ module Api
posts_page = pager(query, query_time_field, data_time_field).response posts_page = pager(query, query_time_field, data_time_field).response
posts_page[:data] = posts_page[:data].map {|post| PostPresenter.new(post, current_user).as_api_response } posts_page[:data] = posts_page[:data].map {|post| PostPresenter.new(post, current_user).as_api_response }
posts_page[:links].delete(:previous) posts_page[:links].delete(:previous)
render json: posts_page render_paged_api_response posts_page
end end
def stream_max_time def stream_max_time

View file

@ -12,7 +12,7 @@ module Api
end end
def index def index
render json: tag_followings_service.index.map(&:name) render json: tag_followings_service.index.pluck(:name)
end end
def create def create

View file

@ -57,7 +57,7 @@ module Api
contacts_query = aspects_service.all_contacts contacts_query = aspects_service.all_contacts
contacts_page = index_pager(contacts_query).response contacts_page = index_pager(contacts_query).response
contacts_page[:data] = contacts_page[:data].map {|c| PersonPresenter.new(c.person).as_api_json } contacts_page[:data] = contacts_page[:data].map {|c| PersonPresenter.new(c.person).as_api_json }
render json: contacts_page render_paged_api_response contacts_page
end end
def photos def photos
@ -66,7 +66,7 @@ module Api
photos_query = Photo.visible(user_for_query, person, :all, Time.current) photos_query = Photo.visible(user_for_query, person, :all, Time.current)
photos_page = time_pager(photos_query).response photos_page = time_pager(photos_query).response
photos_page[:data] = photos_page[:data].map {|photo| PhotoPresenter.new(photo).as_api_json(true) } photos_page[:data] = photos_page[:data].map {|photo| PhotoPresenter.new(photo).as_api_json(true) }
render json: photos_page render_paged_api_response photos_page
end end
def posts def posts
@ -78,7 +78,7 @@ module Api
end end
posts_page = time_pager(posts_query).response posts_page = time_pager(posts_query).response
posts_page[:data] = posts_page[:data].map {|post| PostPresenter.new(post, current_user).as_api_response } posts_page[:data] = posts_page[:data].map {|post| PostPresenter.new(post, current_user).as_api_response }
render json: posts_page render_paged_api_response posts_page
end end
private private

View file

@ -342,6 +342,6 @@ describe Api::V1::AspectsController do
end end
def response_body_data(response) def response_body_data(response)
JSON.parse(response.body)["data"] JSON.parse(response.body)
end end
end end

View file

@ -139,7 +139,7 @@ describe Api::V1::CommentsController do
params: {access_token: access_token_minimum_scopes} params: {access_token: access_token_minimum_scopes}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
comments = response_body_data(response) comments = response_body(response)
expect(comments.length).to eq(2) expect(comments.length).to eq(2)
confirm_comment_format(comments[0], auth.user, @comment_text1) confirm_comment_format(comments[0], auth.user, @comment_text1)
confirm_comment_format(comments[1], auth.user, @comment_text2) confirm_comment_format(comments[1], auth.user, @comment_text2)
@ -435,10 +435,6 @@ describe Api::V1::CommentsController do
JSON.parse(response.body) JSON.parse(response.body)
end end
def response_body_data(response)
JSON.parse(response.body)["data"]
end
private private
# rubocop:disable Metrics/AbcSize # rubocop:disable Metrics/AbcSize

View file

@ -252,7 +252,7 @@ describe Api::V1::ContactsController do
end end
def response_body_data(response) def response_body_data(response)
JSON.parse(response.body)["data"] JSON.parse(response.body)
end end
def aspects_membership_service(user=auth.user) def aspects_membership_service(user=auth.user)

View file

@ -165,7 +165,7 @@ describe Api::V1::ConversationsController do
it "returns all the user conversations" do it "returns all the user conversations" do
get api_v1_conversations_path, params: {access_token: access_token} get api_v1_conversations_path, params: {access_token: access_token}
expect(response.status).to eq(200) expect(response.status).to eq(200)
returned_conversations = response_body_data(response) returned_conversations = response_body(response)
expect(returned_conversations.length).to eq(3) expect(returned_conversations.length).to eq(3)
actual_conversation = returned_conversations.select {|c| c["guid"] == @read_conversation_guid }[0] actual_conversation = returned_conversations.select {|c| c["guid"] == @read_conversation_guid }[0]
confirm_conversation_format(actual_conversation, @read_conversation, [auth.user, alice]) confirm_conversation_format(actual_conversation, @read_conversation, [auth.user, alice])
@ -179,7 +179,7 @@ describe Api::V1::ConversationsController do
params: {only_unread: true, access_token: access_token} params: {only_unread: true, access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response_body_data(response).length).to eq(2) expect(response_body(response).length).to eq(2)
end end
it "returns all the user conversations after a given date" do it "returns all the user conversations after a given date" do
@ -188,7 +188,7 @@ describe Api::V1::ConversationsController do
params: {only_after: @date, access_token: access_token} params: {only_after: @date, access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response_body_data(response).length).to eq(1) expect(response_body(response).length).to eq(1)
end end
context "with improper credentials" do context "with improper credentials" do
@ -366,10 +366,6 @@ describe Api::V1::ConversationsController do
JSON.parse(response.body) JSON.parse(response.body)
end end
def response_body_data(response)
JSON.parse(response.body)["data"]
end
# rubocop:disable Metrics/AbcSize # rubocop:disable Metrics/AbcSize
def confirm_conversation_format(conversation, ref_conversation, ref_participants) def confirm_conversation_format(conversation, ref_conversation, ref_participants)
expect(conversation["guid"]).to_not be_nil expect(conversation["guid"]).to_not be_nil

View file

@ -56,7 +56,7 @@ describe Api::V1::LikesController do
params: {access_token: access_token_minimum_scopes} params: {access_token: access_token_minimum_scopes}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
likes = response_body_data(response) likes = response_body(response)
expect(likes.length).to eq(0) expect(likes.length).to eq(0)
end end
@ -69,7 +69,7 @@ describe Api::V1::LikesController do
params: {access_token: access_token_minimum_scopes} params: {access_token: access_token_minimum_scopes}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
likes = response_body_data(response) likes = response_body(response)
expect(likes.length).to eq(3) expect(likes.length).to eq(3)
confirm_like_format(likes, alice) confirm_like_format(likes, alice)
confirm_like_format(likes, bob) confirm_like_format(likes, bob)
@ -278,8 +278,4 @@ describe Api::V1::LikesController do
def response_body(response) def response_body(response)
JSON.parse(response.body) JSON.parse(response.body)
end end
def response_body_data(response)
JSON.parse(response.body)["data"]
end
end end

View file

@ -161,7 +161,7 @@ describe Api::V1::MessagesController do
private private
def response_body_data(response) def response_body_data(response)
JSON.parse(response.body)["data"] JSON.parse(response.body)
end end
def get_conversation(conversation_id) def get_conversation(conversation_id)

View file

@ -227,7 +227,7 @@ describe Api::V1::NotificationsController do
private private
def response_body_data(response) def response_body_data(response)
JSON.parse(response.body)["data"] JSON.parse(response.body)
end end
# rubocop:disable Metrics/AbcSize # rubocop:disable Metrics/AbcSize

View file

@ -363,7 +363,7 @@ describe Api::V1::PhotosController do
end end
def response_body_data(response) def response_body_data(response)
response_body(response)["data"] response_body(response)
end end
# rubocop:disable Metrics/AbcSize # rubocop:disable Metrics/AbcSize

View file

@ -220,7 +220,7 @@ describe Api::V1::ResharesController do
end end
def response_body_data(response) def response_body_data(response)
JSON.parse(response.body)["data"] JSON.parse(response.body)
end end
# rubocop:disable Metrics/AbcSize # rubocop:disable Metrics/AbcSize

View file

@ -224,6 +224,6 @@ describe Api::V1::SearchController do
end end
def response_body_data(response) def response_body_data(response)
JSON.parse(response.body)["data"] JSON.parse(response.body)
end end
end end

View file

@ -474,7 +474,7 @@ describe Api::V1::StreamsController do
# rubocop:enable Metrics/AbcSize # rubocop:enable Metrics/AbcSize
def response_body_data(response) def response_body_data(response)
JSON.parse(response.body)["data"] JSON.parse(response.body)
end end
def add_tag(name, user) def add_tag(name, user)

View file

@ -316,7 +316,7 @@ describe Api::V1::UsersController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
contacts = response_body_data(response) contacts = response_body(response)
expect(contacts.length).to eq(0) expect(contacts.length).to eq(0)
aspect = auth.user.aspects.create(name: "first") aspect = auth.user.aspects.create(name: "first")
@ -326,7 +326,7 @@ describe Api::V1::UsersController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
contacts = response_body_data(response) contacts = response_body(response)
expect(contacts.length).to eq(1) expect(contacts.length).to eq(1)
confirm_person_format(contacts[0], alice) confirm_person_format(contacts[0], alice)
@ -391,7 +391,7 @@ describe Api::V1::UsersController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
photos = response_body_data(response) photos = response_body(response)
expect(photos.length).to eq(3) expect(photos.length).to eq(3)
guids = photos.map {|photo| photo["guid"] } guids = photos.map {|photo| photo["guid"] }
expect(guids).to include(@public_photo1.guid, @public_photo2.guid, @shared_photo1.guid) expect(guids).to include(@public_photo1.guid, @public_photo2.guid, @shared_photo1.guid)
@ -407,7 +407,7 @@ describe Api::V1::UsersController do
params: {access_token: access_token_public_only_read_only} params: {access_token: access_token_public_only_read_only}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
photos = response_body_data(response) photos = response_body(response)
expect(photos.length).to eq(2) expect(photos.length).to eq(2)
guids = photos.map {|photo| photo["guid"] } guids = photos.map {|photo| photo["guid"] }
expect(guids).to include(@public_photo1.guid, @public_photo2.guid) expect(guids).to include(@public_photo1.guid, @public_photo2.guid)
@ -467,7 +467,7 @@ describe Api::V1::UsersController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
posts = response_body_data(response) posts = response_body(response)
expect(posts.length).to eq(3) expect(posts.length).to eq(3)
guids = posts.map {|post| post["guid"] } guids = posts.map {|post| post["guid"] }
expect(guids).to include(@public_post1.guid, @public_post2.guid, @shared_post1.guid) expect(guids).to include(@public_post1.guid, @public_post2.guid, @shared_post1.guid)
@ -484,7 +484,7 @@ describe Api::V1::UsersController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
posts = response_body_data(response) posts = response_body(response)
expect(posts.length).to eq(3) expect(posts.length).to eq(3)
end end
@ -494,7 +494,7 @@ describe Api::V1::UsersController do
params: {access_token: access_token_public_only_read_only} params: {access_token: access_token_public_only_read_only}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
posts = response_body_data(response) posts = response_body(response)
expect(posts.length).to eq(2) expect(posts.length).to eq(2)
end end
end end
@ -605,8 +605,4 @@ describe Api::V1::UsersController do
def response_body(response) def response_body(response)
JSON.parse(response.body) JSON.parse(response.body)
end end
def response_body_data(response)
response_body(response)["data"]
end
end end