Abstract pagination params in OpenAPI spec

This commit is contained in:
Egor Kislitsyn 2020-04-15 16:45:45 +04:00
parent 8ed162b655
commit 0e647ff55a
No known key found for this signature in database
GPG Key ID: 1B49CB15B71E7805
2 changed files with 57 additions and 73 deletions

View File

@ -3,6 +3,9 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ApiSpec.Helpers do defmodule Pleroma.Web.ApiSpec.Helpers do
alias OpenApiSpex.Operation
alias OpenApiSpex.Schema
def request_body(description, schema_ref, opts \\ []) do def request_body(description, schema_ref, opts \\ []) do
media_types = ["application/json", "multipart/form-data", "application/x-www-form-urlencoded"] media_types = ["application/json", "multipart/form-data", "application/x-www-form-urlencoded"]
@ -24,4 +27,23 @@ def request_body(description, schema_ref, opts \\ []) do
required: opts[:required] || false required: opts[:required] || false
} }
end end
def pagination_params do
[
Operation.parameter(:max_id, :query, :string, "Return items older than this ID"),
Operation.parameter(:min_id, :query, :string, "Return the oldest items newer than this ID"),
Operation.parameter(
:since_id,
:query,
:string,
"Return the newest items newer than this ID"
),
Operation.parameter(
:limit,
:query,
%Schema{type: :integer, default: 20, maximum: 40},
"Limit"
)
]
end
end end

View File

@ -6,7 +6,6 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
alias OpenApiSpex.Operation alias OpenApiSpex.Operation
alias OpenApiSpex.Reference alias OpenApiSpex.Reference
alias OpenApiSpex.Schema alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.Helpers
alias Pleroma.Web.ApiSpec.Schemas.Account alias Pleroma.Web.ApiSpec.Schemas.Account
alias Pleroma.Web.ApiSpec.Schemas.AccountCreateRequest alias Pleroma.Web.ApiSpec.Schemas.AccountCreateRequest
alias Pleroma.Web.ApiSpec.Schemas.AccountCreateResponse alias Pleroma.Web.ApiSpec.Schemas.AccountCreateResponse
@ -21,6 +20,8 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
alias Pleroma.Web.ApiSpec.Schemas.StatusesResponse alias Pleroma.Web.ApiSpec.Schemas.StatusesResponse
alias Pleroma.Web.ApiSpec.Schemas.VisibilityScope alias Pleroma.Web.ApiSpec.Schemas.VisibilityScope
import Pleroma.Web.ApiSpec.Helpers
@spec open_api_operation(atom) :: Operation.t() @spec open_api_operation(atom) :: Operation.t()
def open_api_operation(action) do def open_api_operation(action) do
operation = String.to_existing_atom("#{action}_operation") operation = String.to_existing_atom("#{action}_operation")
@ -35,7 +36,7 @@ def create_operation do
description: description:
"Creates a user and account records. Returns an account access token for the app that initiated the request. The app should save this token for later, and should wait for the user to confirm their account by clicking a link in their email inbox.", "Creates a user and account records. Returns an account access token for the app that initiated the request. The app should save this token for later, and should wait for the user to confirm their account by clicking a link in their email inbox.",
operationId: "AccountController.create", operationId: "AccountController.create",
requestBody: Helpers.request_body("Parameters", AccountCreateRequest, required: true), requestBody: request_body("Parameters", AccountCreateRequest, required: true),
responses: %{ responses: %{
200 => Operation.response("Account", "application/json", AccountCreateResponse) 200 => Operation.response("Account", "application/json", AccountCreateResponse)
} }
@ -62,8 +63,7 @@ def update_credentials_operation do
description: "Update the user's display and preferences.", description: "Update the user's display and preferences.",
operationId: "AccountController.update_credentials", operationId: "AccountController.update_credentials",
security: [%{"oAuth" => ["write:accounts"]}], security: [%{"oAuth" => ["write:accounts"]}],
requestBody: requestBody: request_body("Parameters", AccountUpdateCredentialsRequest, required: true),
Helpers.request_body("Parameters", AccountUpdateCredentialsRequest, required: true),
responses: %{ responses: %{
200 => Operation.response("Account", "application/json", Account) 200 => Operation.response("Account", "application/json", Account)
} }
@ -114,7 +114,8 @@ def statuses_operation do
operationId: "AccountController.statuses", operationId: "AccountController.statuses",
description: description:
"Statuses posted to the given account. Public (for public statuses only), or user token + `read:statuses` (for private statuses the user is authorized to see)", "Statuses posted to the given account. Public (for public statuses only), or user token + `read:statuses` (for private statuses the user is authorized to see)",
parameters: [ parameters:
[
%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}, %Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
Operation.parameter(:pinned, :query, BooleanLike, "Include only pinned statuses"), Operation.parameter(:pinned, :query, BooleanLike, "Include only pinned statuses"),
Operation.parameter(:tagged, :query, :string, "With tag"), Operation.parameter(:tagged, :query, :string, "With tag"),
@ -136,27 +137,8 @@ def statuses_operation do
:query, :query,
%Schema{type: :array, items: VisibilityScope}, %Schema{type: :array, items: VisibilityScope},
"Exclude visibilities" "Exclude visibilities"
),
Operation.parameter(:max_id, :query, :string, "Return statuses older than this ID"),
Operation.parameter(
:min_id,
:query,
:string,
"Return the oldest statuses newer than this ID"
),
Operation.parameter(
:since_id,
:query,
:string,
"Return the newest statuses newer than this ID"
),
Operation.parameter(
:limit,
:query,
%Schema{type: :integer, default: 20, maximum: 40},
"Limit"
) )
], ] ++ pagination_params(),
responses: %{ responses: %{
200 => Operation.response("Statuses", "application/json", StatusesResponse) 200 => Operation.response("Statuses", "application/json", StatusesResponse)
} }
@ -171,18 +153,8 @@ def followers_operation do
security: [%{"oAuth" => ["read:accounts"]}], security: [%{"oAuth" => ["read:accounts"]}],
description: description:
"Accounts which follow the given account, if network is not hidden by the account owner.", "Accounts which follow the given account, if network is not hidden by the account owner.",
parameters: [ parameters:
%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}, [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}] ++ pagination_params(),
Operation.parameter(:max_id, :query, :string, "Max ID"),
Operation.parameter(:min_id, :query, :string, "Mix ID"),
Operation.parameter(:since_id, :query, :string, "Since ID"),
Operation.parameter(
:limit,
:query,
%Schema{type: :integer, default: 20, maximum: 40},
"Limit"
)
],
responses: %{ responses: %{
200 => Operation.response("Accounts", "application/json", AccountsResponse) 200 => Operation.response("Accounts", "application/json", AccountsResponse)
} }
@ -197,18 +169,8 @@ def following_operation do
security: [%{"oAuth" => ["read:accounts"]}], security: [%{"oAuth" => ["read:accounts"]}],
description: description:
"Accounts which the given account is following, if network is not hidden by the account owner.", "Accounts which the given account is following, if network is not hidden by the account owner.",
parameters: [ parameters:
%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}, [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}] ++ pagination_params(),
Operation.parameter(:max_id, :query, :string, "Max ID"),
Operation.parameter(:min_id, :query, :string, "Mix ID"),
Operation.parameter(:since_id, :query, :string, "Since ID"),
Operation.parameter(
:limit,
:query,
%Schema{type: :integer, default: 20, maximum: 40},
"Limit"
)
],
responses: %{200 => Operation.response("Accounts", "application/json", AccountsResponse)} responses: %{200 => Operation.response("Accounts", "application/json", AccountsResponse)}
} }
end end
@ -267,7 +229,7 @@ def mute_operation do
summary: "Mute", summary: "Mute",
operationId: "AccountController.mute", operationId: "AccountController.mute",
security: [%{"oAuth" => ["follow", "write:mutes"]}], security: [%{"oAuth" => ["follow", "write:mutes"]}],
requestBody: Helpers.request_body("Parameters", AccountMuteRequest), requestBody: request_body("Parameters", AccountMuteRequest),
description: description:
"Mute the given account. Clients should filter statuses and notifications from this account, if received (e.g. due to a boost in the Home timeline).", "Mute the given account. Clients should filter statuses and notifications from this account, if received (e.g. due to a boost in the Home timeline).",
parameters: [ parameters: [
@ -334,7 +296,7 @@ def follows_operation do
summary: "Follows", summary: "Follows",
operationId: "AccountController.follows", operationId: "AccountController.follows",
security: [%{"oAuth" => ["follow", "write:follows"]}], security: [%{"oAuth" => ["follow", "write:follows"]}],
requestBody: Helpers.request_body("Parameters", AccountFollowsRequest, required: true), requestBody: request_body("Parameters", AccountFollowsRequest, required: true),
responses: %{ responses: %{
200 => Operation.response("Account", "application/json", Account) 200 => Operation.response("Account", "application/json", Account)
} }