diff --git a/lib/helldivers_2_web/api_spec.ex b/lib/helldivers_2_web/api_spec.ex index 2552c71..18ba796 100644 --- a/lib/helldivers_2_web/api_spec.ex +++ b/lib/helldivers_2_web/api_spec.ex @@ -1,5 +1,5 @@ defmodule Helldivers2Web.ApiSpec do - alias OpenApiSpex.{Info, OpenApi, Paths, Server} + alias OpenApiSpex.{Info, OpenApi, Paths, Server, Schema, Header} alias Helldivers2Web.{Endpoint, Router} @behaviour OpenApi @@ -20,4 +20,25 @@ defmodule Helldivers2Web.ApiSpec do # Discover request/response schemas from path specs |> OpenApiSpex.resolve_schema_modules() end + + @doc "Generates the default options for responses, currently generates headers from `rate_limit_headers/1`." + def default_options(options \\ []), do: options ++ [headers: rate_limit_headers()] + + @doc "Generates the headers of rate limit added by `Helldivers2Web.Plugs.RateLimit`." + def rate_limit_headers(map \\ %{}) do + Enum.into(map, %{ + "x-ratelimit-limit" => %Header{ + schema: %Schema{type: :number}, + description: "The total amount of requests that can be made in the time window" + }, + "x-ratelimit-remaining" => %Header{ + schema: %Schema{type: :number}, + description: "The amount of requests remaining that can be made in the time window" + }, + "x-ratelimit-reset" => %Header{ + schema: %Schema{type: :number}, + description: "The unix epoch timestamp (in seconds) when more requests can be made" + } + }) + end end diff --git a/lib/helldivers_2_web/controllers/api/war_season_controller.ex b/lib/helldivers_2_web/controllers/api/war_season_controller.ex index 4ab9a55..de838db 100644 --- a/lib/helldivers_2_web/controllers/api/war_season_controller.ex +++ b/lib/helldivers_2_web/controllers/api/war_season_controller.ex @@ -14,7 +14,7 @@ defmodule Helldivers2Web.Api.WarSeasonController do summary: "Get an overview of all available war seasons", responses: [ ok: - {"Warseason overview", "application/json", WarSeasonOverview}, + {"Warseason overview", "application/json", WarSeasonOverview, Helldivers2Web.ApiSpec.default_options()}, too_many_requests: TooManyRequestsSchema.response() ] diff --git a/lib/helldivers_2_web/schemas/campaign_schema.ex b/lib/helldivers_2_web/schemas/campaign_schema.ex index 56baee4..1e984cb 100644 --- a/lib/helldivers_2_web/schemas/campaign_schema.ex +++ b/lib/helldivers_2_web/schemas/campaign_schema.ex @@ -4,7 +4,7 @@ defmodule Helldivers2Web.Schemas.CampaignSchema do require OpenApiSpex @doc "Generates a schema for a single homeworld schema response" - def response(), do: {"Campaign response", "application/json", __MODULE__} + def response(), do: {"Campaign response", "application/json", __MODULE__, Helldivers2Web.ApiSpec.default_options()} OpenApiSpex.schema(%{ description: "Contains information about a currently active campaign", diff --git a/lib/helldivers_2_web/schemas/global_event_schema.ex b/lib/helldivers_2_web/schemas/global_event_schema.ex index ebef760..52512cd 100644 --- a/lib/helldivers_2_web/schemas/global_event_schema.ex +++ b/lib/helldivers_2_web/schemas/global_event_schema.ex @@ -4,9 +4,9 @@ defmodule Helldivers2Web.Schemas.GlobalEventSchema do require OpenApiSpex @doc "Generates a schema for a single homeworld schema response" - def response(), do: {"Global event response", "application/json", __MODULE__} + def response(), do: {"Global event response", "application/json", __MODULE__, Helldivers2Web.ApiSpec.default_options()} - def responses(), do: {"Global events response", "application/json", %Schema{type: :array, items: __MODULE__}} + def responses(), do: {"Global events response", "application/json", %Schema{type: :array, items: __MODULE__}, Helldivers2Web.ApiSpec.default_options()} OpenApiSpex.schema(%{ description: "Contains information about a global event, past and present", diff --git a/lib/helldivers_2_web/schemas/home_world_schema.ex b/lib/helldivers_2_web/schemas/home_world_schema.ex index f536652..8d2b775 100644 --- a/lib/helldivers_2_web/schemas/home_world_schema.ex +++ b/lib/helldivers_2_web/schemas/home_world_schema.ex @@ -4,7 +4,7 @@ defmodule Helldivers2Web.Schemas.HomeWorldSchema do require OpenApiSpex @doc "Generates a schema for a single homeworld schema response" - def response(), do: {"Homeworld response", "application/json", __MODULE__} + def response(), do: {"Homeworld response", "application/json", __MODULE__, Helldivers2Web.ApiSpec.default_options()} OpenApiSpex.schema(%{ description: "Homeworld information of a given faction", diff --git a/lib/helldivers_2_web/schemas/joint_operation_schema.ex b/lib/helldivers_2_web/schemas/joint_operation_schema.ex index faecd2f..2706dc7 100644 --- a/lib/helldivers_2_web/schemas/joint_operation_schema.ex +++ b/lib/helldivers_2_web/schemas/joint_operation_schema.ex @@ -4,7 +4,7 @@ defmodule Helldivers2Web.Schemas.JointOperationSchema do require OpenApiSpex @doc "Generates a schema for a single homeworld schema response" - def response(), do: {"Joint operation response", "application/json", __MODULE__} + def response(), do: {"Joint operation response", "application/json", __MODULE__, Helldivers2Web.ApiSpec.default_options()} OpenApiSpex.schema(%{ description: "Contains information about a currently joint operation", diff --git a/lib/helldivers_2_web/schemas/not_found_schema.ex b/lib/helldivers_2_web/schemas/not_found_schema.ex index 4d11e35..ca35286 100644 --- a/lib/helldivers_2_web/schemas/not_found_schema.ex +++ b/lib/helldivers_2_web/schemas/not_found_schema.ex @@ -2,7 +2,7 @@ defmodule Helldivers2Web.Schemas.NotFoundSchema do alias OpenApiSpex.Schema require OpenApiSpex - def response(), do: {"Resource not found", "application/json", __MODULE__} + def response(), do: {"Resource not found", "application/json", __MODULE__, Helldivers2Web.ApiSpec.default_options()} OpenApiSpex.schema(%{ description: "The resource you tried to retrieve could not be found", diff --git a/lib/helldivers_2_web/schemas/planet_event_schema.ex b/lib/helldivers_2_web/schemas/planet_event_schema.ex index 4cf923e..b6dc493 100644 --- a/lib/helldivers_2_web/schemas/planet_event_schema.ex +++ b/lib/helldivers_2_web/schemas/planet_event_schema.ex @@ -7,7 +7,7 @@ defmodule Helldivers2Web.Schemas.PlanetEventSchema do alias OpenApiSpex.Schema @doc "Generates a schema for a single homeworld schema response" - def response(), do: {"Planet event response", "application/json", __MODULE__} + def response(), do: {"Planet event response", "application/json", __MODULE__, Helldivers2Web.ApiSpec.default_options()} OpenApiSpex.schema(%{ description: "An event occuring on a specific planet for a limited time", diff --git a/lib/helldivers_2_web/schemas/planet_schema.ex b/lib/helldivers_2_web/schemas/planet_schema.ex index de76d89..b2eff3f 100644 --- a/lib/helldivers_2_web/schemas/planet_schema.ex +++ b/lib/helldivers_2_web/schemas/planet_schema.ex @@ -3,11 +3,11 @@ defmodule Helldivers2Web.Schemas.PlanetSchema do require OpenApiSpex @doc "Generates a schema for a single planet schema response" - def response(), do: {"Planet response", "application/json", __MODULE__} + def response(), do: {"Planet response", "application/json", __MODULE__, Helldivers2Web.ApiSpec.default_options()} @doc "Generates a schema for an array of planet schemas" def responses(), - do: {"Planets response", "application/json", %Schema{type: :array, items: __MODULE__}} + do: {"Planets response", "application/json", %Schema{type: :array, items: __MODULE__}, Helldivers2Web.ApiSpec.default_options()} OpenApiSpex.schema(%{ description: "Represents a planet in the galactic war that must receive Managed democracy", diff --git a/lib/helldivers_2_web/schemas/planet_status_schema.ex b/lib/helldivers_2_web/schemas/planet_status_schema.ex index a2e7a03..e3adf0f 100644 --- a/lib/helldivers_2_web/schemas/planet_status_schema.ex +++ b/lib/helldivers_2_web/schemas/planet_status_schema.ex @@ -5,7 +5,7 @@ defmodule Helldivers2Web.Schemas.PlanetStatusSchema do alias Helldivers2Web.Schemas.PlanetSchema @doc "Generates a schema for a single war info schema response" - def response(), do: {"Planet status response", "application/json", __MODULE__} + def response(), do: {"Planet status response", "application/json", __MODULE__, Helldivers2Web.ApiSpec.default_options()} OpenApiSpex.schema(%{ description: "The current offense status of a planet (owner, health, regen, player count)", diff --git a/lib/helldivers_2_web/schemas/too_many_requests_schema.ex b/lib/helldivers_2_web/schemas/too_many_requests_schema.ex index 09e0677..463e7f5 100644 --- a/lib/helldivers_2_web/schemas/too_many_requests_schema.ex +++ b/lib/helldivers_2_web/schemas/too_many_requests_schema.ex @@ -1,8 +1,21 @@ defmodule Helldivers2Web.Schemas.TooManyRequestsSchema do + alias Helldivers2Web.ApiSpec + alias OpenApiSpex.Header alias OpenApiSpex.Schema require OpenApiSpex - def response(), do: {"Rate limit exceeded", "application/json", __MODULE__} + def response() do + {"Rate limit exceeded", "application/json", __MODULE__, + [ + headers: + ApiSpec.rate_limit_headers(%{ + "retry-after" => %Header{ + schema: %Schema{type: :number}, + description: "The amount of seconds to wait before making new requests" + } + }) + ]} + end OpenApiSpex.schema(%{ description: "You're making too many requests in a limited span of time", diff --git a/lib/helldivers_2_web/schemas/war_info_schema.ex b/lib/helldivers_2_web/schemas/war_info_schema.ex index 2dfdfde..390fb77 100644 --- a/lib/helldivers_2_web/schemas/war_info_schema.ex +++ b/lib/helldivers_2_web/schemas/war_info_schema.ex @@ -5,7 +5,7 @@ defmodule Helldivers2Web.Schemas.WarInfoSchema do alias Helldivers2Web.Schemas.{PlanetSchema, HomeWorldSchema} @doc "Generates a schema for a single war info schema response" - def response(), do: {"War info response", "application/json", __MODULE__} + def response(), do: {"War info response", "application/json", __MODULE__, Helldivers2Web.ApiSpec.default_options()} OpenApiSpex.schema(%{ description: "Global overview of the war, it's planets, capitals etc", diff --git a/lib/helldivers_2_web/schemas/war_season_overview.ex b/lib/helldivers_2_web/schemas/war_season_overview.ex index 7861314..225b81e 100644 --- a/lib/helldivers_2_web/schemas/war_season_overview.ex +++ b/lib/helldivers_2_web/schemas/war_season_overview.ex @@ -2,7 +2,7 @@ defmodule Helldivers2Web.Schemas.WarSeasonOverview do alias OpenApiSpex.Schema require OpenApiSpex - def response(), do: {"Available war seasons", "application/json", __MODULE__} + def response(), do: {"Available war seasons", "application/json", __MODULE__, Helldivers2Web.ApiSpec.default_options()} OpenApiSpex.schema(%{ description: "An overview of the available war seasons (and the current)", diff --git a/lib/helldivers_2_web/schemas/war_status_schema.ex b/lib/helldivers_2_web/schemas/war_status_schema.ex index e1b1d23..8302652 100644 --- a/lib/helldivers_2_web/schemas/war_status_schema.ex +++ b/lib/helldivers_2_web/schemas/war_status_schema.ex @@ -10,7 +10,7 @@ defmodule Helldivers2Web.Schemas.WarStatusSchema do alias OpenApiSpex.Schema @doc "Generates a schema for a single war info schema response" - def response(), do: {"War status response", "application/json", __MODULE__} + def response(), do: {"War status response", "application/json", __MODULE__, Helldivers2Web.ApiSpec.default_options()} OpenApiSpex.schema(%{ description: "Current status of the Helldivers offensive in the galactic war",