diff --git a/public/v1/components/headers.yaml b/public/v1/components/headers.yaml index e309b507..5edbb250 100644 --- a/public/v1/components/headers.yaml +++ b/public/v1/components/headers.yaml @@ -41,3 +41,8 @@ components: required: false schema: type: integer + RetryAfter: + description: The number of seconds remaining until the request of this measurement is available again. + required: true + schema: + type: integer diff --git a/public/v1/components/responses.yaml b/public/v1/components/responses.yaml index 3d7c3f52..93d74f86 100644 --- a/public/v1/components/responses.yaml +++ b/public/v1/components/responses.yaml @@ -169,6 +169,35 @@ components: $ref: 'examples.yaml#/components/examples/getMtrMeasurementResponse' httpMeasurement: $ref: 'examples.yaml#/components/examples/getHttpMeasurementResponse' + measurement429: + description: | + If you've exceeded the API rate limit, you'll receive status `429 Too Many Requests` and a body containing more information about the error. + headers: + Retry-After: + $ref: 'headers.yaml#/components/headers/RetryAfter' + content: + application/json: + schema: + type: object + required: + - error + properties: + error: + type: object + required: + - type + - message + properties: + type: + type: string + message: + type: string + examples: + json: + value: + error: + type: too_many_requests + message: Too Many Requests. probes200: description: | A successful request returns status `200 OK` and a body containing a list of all probes currently online and their metadata. diff --git a/public/v1/spec.yaml b/public/v1/spec.yaml index 80dbf93c..404114db 100644 --- a/public/v1/spec.yaml +++ b/public/v1/spec.yaml @@ -105,8 +105,13 @@ paths: $ref: 'components/responses.yaml#/components/responses/measurement200' '404': $ref: 'components/responses.yaml#/components/responses/404' + '429': + $ref: 'components/responses.yaml#/components/responses/measurement429' tags: - Measurements + security: + - {} + - bearerAuth: [] /v1/probes: get: summary: List probes currently online diff --git a/src/lib/rate-limiter/rate-limiter-get.ts b/src/lib/rate-limiter/rate-limiter-get.ts index 1ba00043..ef9edb41 100644 --- a/src/lib/rate-limiter/rate-limiter-get.ts +++ b/src/lib/rate-limiter/rate-limiter-get.ts @@ -55,7 +55,7 @@ export const getMeasurementRateLimit = async (ctx: ExtendedContext, next: Next) } catch (error) { if (error instanceof RateLimiterRes) { setRateLimitHeaders(ctx, error); - throw createHttpError(429, 'Too Many Requests', { type: 'too_many_requests' }); + throw createHttpError(429, 'Too Many Requests.', { type: 'too_many_requests' }); } throw createHttpError(500); diff --git a/src/measurement/route/get-measurement.ts b/src/measurement/route/get-measurement.ts index d3ae3203..0f4e75ca 100644 --- a/src/measurement/route/get-measurement.ts +++ b/src/measurement/route/get-measurement.ts @@ -4,6 +4,7 @@ import { getMeasurementStore } from '../store.js'; import { corsAuthHandler } from '../../lib/http/middleware/cors.js'; import { authenticate } from '../../lib/http/middleware/authenticate.js'; import { getMeasurementRateLimit } from '../../lib/rate-limiter/rate-limiter-get.js'; +import createHttpError from 'http-errors'; const store = getMeasurementStore(); @@ -18,8 +19,7 @@ const handle = async (ctx: ParameterizedContext