341 lines
9.7 KiB
YAML
341 lines
9.7 KiB
YAML
basePath: /
|
|
definitions:
|
|
api.CategoriesResponse:
|
|
properties:
|
|
categories:
|
|
items:
|
|
$ref: '#/definitions/api.Category'
|
|
type: array
|
|
type: object
|
|
api.Category:
|
|
properties:
|
|
id:
|
|
example: 1
|
|
type: integer
|
|
name:
|
|
example: documentary
|
|
type: string
|
|
type: object
|
|
api.CompleteRequest:
|
|
properties:
|
|
categoryIds:
|
|
example:
|
|
- 1
|
|
- 2
|
|
items:
|
|
type: integer
|
|
type: array
|
|
description:
|
|
example: A behind-the-scenes look at the evening bulletin.
|
|
type: string
|
|
fileName:
|
|
example: interview-cut.mov
|
|
type: string
|
|
key:
|
|
example: videos/a1b2c3d4e5f6.mov
|
|
type: string
|
|
tags:
|
|
example: media, press, riyadh
|
|
type: string
|
|
title:
|
|
example: Inside the Newsroom
|
|
type: string
|
|
type: object
|
|
api.CompleteResponse:
|
|
properties:
|
|
categoryIds:
|
|
example:
|
|
- 1
|
|
- 2
|
|
items:
|
|
type: integer
|
|
type: array
|
|
createdAt:
|
|
type: string
|
|
description:
|
|
example: A behind-the-scenes look at the evening bulletin.
|
|
type: string
|
|
fileName:
|
|
example: interview-cut.mov
|
|
type: string
|
|
id:
|
|
example: 0199f3a1-7c2e-7b21-9f0d-1a2b3c4d5e6f
|
|
type: string
|
|
mediaConvertJobId:
|
|
example: 1755300000000-abcdef
|
|
type: string
|
|
sizeBytes:
|
|
example: 60
|
|
type: integer
|
|
status:
|
|
enum:
|
|
- processing
|
|
- ready
|
|
- failed
|
|
example: processing
|
|
type: string
|
|
storageKey:
|
|
example: videos/a1b2c3d4e5f6.mov
|
|
type: string
|
|
tags:
|
|
example: media, press, riyadh
|
|
type: string
|
|
title:
|
|
example: Inside the Newsroom
|
|
type: string
|
|
updatedAt:
|
|
type: string
|
|
type: object
|
|
api.HealthResponse:
|
|
properties:
|
|
status:
|
|
example: ok
|
|
type: string
|
|
type: object
|
|
api.PresignRequest:
|
|
properties:
|
|
contentType:
|
|
enum:
|
|
- video/mp4
|
|
- video/quicktime
|
|
example: video/quicktime
|
|
type: string
|
|
fileName:
|
|
example: interview-cut.mov
|
|
type: string
|
|
type: object
|
|
api.PresignResponse:
|
|
properties:
|
|
key:
|
|
example: videos/a1b2c3d4e5f6.mov
|
|
type: string
|
|
uploadUrl:
|
|
example: https://raw-uploads-bucket.s3.amazonaws.com/videos/a1b2....mov?X-Amz-Signature=...
|
|
type: string
|
|
type: object
|
|
api.ProblemDetails:
|
|
properties:
|
|
detail:
|
|
example: The 'title' field was absent or contained only whitespace. Every
|
|
video needs a non-empty title.
|
|
type: string
|
|
status:
|
|
example: 422
|
|
type: integer
|
|
title:
|
|
example: Title is required.
|
|
type: string
|
|
type:
|
|
example: about:blank
|
|
type: string
|
|
type: object
|
|
api.VideoResponse:
|
|
properties:
|
|
categoryIds:
|
|
example:
|
|
- 1
|
|
- 2
|
|
items:
|
|
type: integer
|
|
type: array
|
|
createdAt:
|
|
type: string
|
|
description:
|
|
example: A behind-the-scenes look at the evening bulletin.
|
|
type: string
|
|
fileName:
|
|
example: interview-cut.mov
|
|
type: string
|
|
id:
|
|
example: 0199f3a1-7c2e-7b21-9f0d-1a2b3c4d5e6f
|
|
type: string
|
|
mediaConvertJobId:
|
|
example: 1755300000000-abcdef
|
|
type: string
|
|
sizeBytes:
|
|
example: 60
|
|
type: integer
|
|
status:
|
|
enum:
|
|
- processing
|
|
- ready
|
|
- failed
|
|
example: processing
|
|
type: string
|
|
storageKey:
|
|
example: videos/a1b2c3d4e5f6.mov
|
|
type: string
|
|
tags:
|
|
example: media, press, riyadh
|
|
type: string
|
|
title:
|
|
example: Inside the Newsroom
|
|
type: string
|
|
updatedAt:
|
|
type: string
|
|
type: object
|
|
info:
|
|
contact: {}
|
|
description: 'JSON API for ingesting videos into the Thamanyah catalogue. Uploads
|
|
are two-step: presign, PUT the file straight to S3, then register the video to
|
|
queue transcoding.'
|
|
title: Thamanyah CMS API
|
|
version: "1.0"
|
|
paths:
|
|
/api/categories:
|
|
get:
|
|
description: Returns the fixed lookup set of categories a video can belong to,
|
|
each with the id used to reference it. The `id` values from this list are
|
|
the only ones accepted in the `categoryIds` field of POST /api/videos.
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
$ref: '#/definitions/api.CategoriesResponse'
|
|
"500":
|
|
description: Categories could not be read from the database
|
|
schema:
|
|
$ref: '#/definitions/api.ProblemDetails'
|
|
summary: List video categories
|
|
tags:
|
|
- categories
|
|
/api/videos:
|
|
post:
|
|
consumes:
|
|
- application/json
|
|
description: Step 2 of the upload flow. Takes the storage key returned by POST
|
|
/api/videos/presign — after the file has been PUT to the presigned URL — submits
|
|
a MediaConvert transcoding job, and persists the video with its category links.
|
|
The returned record has status "processing" — one of the states "processing",
|
|
"ready" or "failed" — though nothing currently moves it on once transcoding
|
|
finishes.
|
|
parameters:
|
|
- description: Video metadata plus the storage key from the presign step. title,
|
|
key and categoryIds are required; categoryIds must hold at least one id
|
|
from GET /api/categories.
|
|
in: body
|
|
name: request
|
|
required: true
|
|
schema:
|
|
$ref: '#/definitions/api.CompleteRequest'
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"201":
|
|
description: Created
|
|
schema:
|
|
$ref: '#/definitions/api.CompleteResponse'
|
|
"400":
|
|
description: Request body was not valid JSON
|
|
schema:
|
|
$ref: '#/definitions/api.ProblemDetails'
|
|
"404":
|
|
description: categoryIds referenced a category that does not exist
|
|
schema:
|
|
$ref: '#/definitions/api.ProblemDetails'
|
|
"409":
|
|
description: key has already been registered by an earlier request
|
|
schema:
|
|
$ref: '#/definitions/api.ProblemDetails'
|
|
"422":
|
|
description: title was empty, key was missing or not a key issued by this
|
|
API, or categoryIds was empty
|
|
schema:
|
|
$ref: '#/definitions/api.ProblemDetails'
|
|
"500":
|
|
description: Categories could not be read, the key could not be checked,
|
|
the transcoding job could not be queued, or the video record could not
|
|
be saved
|
|
schema:
|
|
$ref: '#/definitions/api.ProblemDetails'
|
|
summary: Register an uploaded video
|
|
tags:
|
|
- videos
|
|
/api/videos/{id}:
|
|
get:
|
|
description: 'Returns the catalogue record for one video, including the status
|
|
its transcoding job has reached. This is how a client follows an upload after
|
|
POST /api/videos: the record starts "processing" and moves to "ready" or "failed"
|
|
once MediaConvert reports the job finished.'
|
|
parameters:
|
|
- description: The video's id, as returned by POST /api/videos
|
|
in: path
|
|
name: id
|
|
required: true
|
|
type: string
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
$ref: '#/definitions/api.VideoResponse'
|
|
"404":
|
|
description: No video has that id
|
|
schema:
|
|
$ref: '#/definitions/api.ProblemDetails'
|
|
"500":
|
|
description: The video could not be read from the database
|
|
schema:
|
|
$ref: '#/definitions/api.ProblemDetails'
|
|
summary: Read a video
|
|
tags:
|
|
- videos
|
|
/api/videos/presign:
|
|
post:
|
|
consumes:
|
|
- application/json
|
|
description: Step 1 of the upload flow. Returns a short-lived presigned S3 URL
|
|
that the client PUTs the video file to directly, plus the storage key identifying
|
|
it. The submitted contentType is signed into that URL, so the PUT must carry
|
|
an identical Content-Type header or S3 rejects it as a signature mismatch.
|
|
Once the PUT succeeds, pass the key to POST /api/videos to register the video
|
|
and start transcoding. The file itself never passes through this API.
|
|
parameters:
|
|
- description: Name and media type of the file to be uploaded. contentType must
|
|
be exactly 'video/mp4' or 'video/quicktime'.
|
|
in: body
|
|
name: request
|
|
required: true
|
|
schema:
|
|
$ref: '#/definitions/api.PresignRequest'
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
$ref: '#/definitions/api.PresignResponse'
|
|
"400":
|
|
description: Request body was not valid JSON
|
|
schema:
|
|
$ref: '#/definitions/api.ProblemDetails'
|
|
"422":
|
|
description: contentType was not 'video/mp4' or 'video/quicktime'
|
|
schema:
|
|
$ref: '#/definitions/api.ProblemDetails'
|
|
"500":
|
|
description: Upload URL could not be issued
|
|
schema:
|
|
$ref: '#/definitions/api.ProblemDetails'
|
|
summary: Create a presigned upload URL
|
|
tags:
|
|
- videos
|
|
/health:
|
|
get:
|
|
description: Reports that the service is up and serving. Used as the ALB target
|
|
group health check; it does not verify the database or S3 connections.
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
$ref: '#/definitions/api.HealthResponse'
|
|
summary: Health check
|
|
tags:
|
|
- system
|
|
swagger: "2.0"
|