diff --git a/app/controllers/api/v0/videos_controller.rb b/app/controllers/api/v0/videos_controller.rb index c57118af0..32f9907c3 100644 --- a/app/controllers/api/v0/videos_controller.rb +++ b/app/controllers/api/v0/videos_controller.rb @@ -10,12 +10,17 @@ module Api @video_articles = Article.with_video. includes([:user]). - select(:id, :video, :path, :title, :video_thumbnail_url, :user_id, :video_duration_in_seconds). - order("hotness_score DESC"). + select(INDEX_ATTRIBUTES_FOR_SERIALIZATION). + order(hotness_score: :desc). page(page).per(num) set_surrogate_key_header "videos", Article.table_key, @video_articles.map(&:record_key) end + + INDEX_ATTRIBUTES_FOR_SERIALIZATION = %i[ + id video path title video_thumbnail_url user_id video_duration_in_seconds + ].freeze + private_constant :INDEX_ATTRIBUTES_FOR_SERIALIZATION end end end diff --git a/docs/api_v0.yml b/docs/api_v0.yml index 13aae4d10..0d3b0ad09 100644 --- a/docs/api_v0.yml +++ b/docs/api_v0.yml @@ -13,7 +13,7 @@ info: Dates and date times, unless otherwise specified, must be in the [RFC 3339](https://tools.ietf.org/html/rfc3339) format. - version: "0.6.7" + version: "0.7.0" termsOfService: https://dev.to/terms contact: name: DEV Team @@ -493,6 +493,48 @@ components: description: Text color (hexadecimal) type: string + ArticleVideo: + type: object + required: + - type_of + - id + - path + - cloudinary_video_url + - title + - user_id + - video_duration_in_minutes + - user + properties: + type_of: + type: string + id: + type: integer + format: int32 + path: + type: string + cloudinary_video_url: + description: The preview image of the video + type: string + format: url + title: + type: string + user_id: + type: integer + format: int32 + video_duration_in_minutes: + description: | + The duration of the video. + + If the video duration is below 1 hour, the format will be `mm:ss`, + if it's 1 hour or above the format will be `h:mm:ss`. + type: string + user: + type: object + properties: + name: + description: The user's name + type: string + Comment: type: object required: @@ -562,7 +604,7 @@ components: type: string id: type: integer - format: int32 + format: int64 title: type: string slug: @@ -641,7 +683,7 @@ components: Only users belonging to an organization can assign the listing to it. type: integer - format: int32 + format: int64 action: description: Set it to "draft" to create an unpublished listing type: string @@ -785,7 +827,7 @@ components: properties: id: type: integer - format: int64 + format: int32 name: type: string bg_color_hex: @@ -795,6 +837,49 @@ components: description: Text color (hexadecimal) type: string + User: + type: object + required: + - type_of + - id + - username + - name + - summary + - twitter_username + - github_username + - website_url + - location + - joined_at + - profile_image + properties: + type_of: + type: string + id: + type: integer + format: int32 + username: + type: string + name: + type: string + summary: + type: string + twitter_username: + type: string + github_username: + type: string + website_url: + type: string + format: url + location: + type: string + joined_at: + description: Date of joining (formatted with strftime `"%b %e, %Y"`) + type: string + profile_image: + description: Profile image (320x320) + type: string + format: url + WebhookCreate: description: Webhook creation payload type: object @@ -1020,6 +1105,17 @@ components: series: Hello series canonical_url: https://example.com/blog/hello organization_id: 1234 + ArticleVideo: + value: + - type_of: video_article + id: 273532 + path: "/devteam/basecs-depth-first-search-implementing-4kkl" + cloudinary_video_url: https://res.cloudinary.com/....png + title: 'BaseCS: Depth First Search Implementing' + user_id: 2882 + video_duration_in_minutes: '11:47' + user: + name: Vaidehi Joshi Comments: value: @@ -1353,6 +1449,20 @@ components: bg_color_hex: "#562765" text_color_hex: "#ffffff" + User: + value: + type_of: user + id: 1234 + username: bob + name: bob + summary: Hello, world + twitter_username: bob + github_username: bob + website_url: + location: New York + joined_at: Jan 1, 2017 + profile_image: https://res.cloudinary.com/...jpeg + WebhookCreate: value: webhook_endpoint: @@ -1393,6 +1503,8 @@ tags: description: Tags for articles - name: users description: Users own resources that require authentication + - name: videos + description: Video articles - name: webhooks description: Webhooks are HTTP endpoints registered to receive events @@ -2386,7 +2498,7 @@ paths: description: Id of the listing schema: type: integer - format: int32 + format: int64 example: 1 responses: "200": @@ -2433,7 +2545,7 @@ paths: description: Id of the listing schema: type: integer - format: int32 + format: int64 example: 1184 requestBody: description: | @@ -2600,7 +2712,7 @@ paths: This endpoint allows the client to retrieve a list of tags that can be used to tag articles. - It will only return tags ordered by popularity. + It will return tags ordered by popularity. It supports pagination, each page will contain `10` tags by default. tags: @@ -2638,6 +2750,149 @@ paths: source: | curl https://dev.to/api/tags + /users/{id}: + get: + operationId: getUser + summary: A user + description: | + This endpoint allows the client to retrieve a single user, either by + id or by the user's username + tags: + - users + parameters: + - name: id + in: path + required: true + description: | + Id of the user. + + It can be either of the following two values: + + - an integer representing the id of the user + - the string `by_username` (needs to be used in conjuction with the param `url`) + schema: + type: string + example: "1" + - name: url + in: query + description: Username of the user + schema: + type: string + example: ben + responses: + "200": + description: A user + content: + application/json: + schema: + $ref: "#/components/schemas/User" + examples: + user-success: + $ref: "#/components/examples/User" + "404": + description: Resource not found + content: + application/json: + schema: + $ref: "#/components/schemas/APIError" + examples: + user-not-found: + $ref: "#/components/examples/ErrorNotFound" + x-code-samples: + - lang: Shell + label: curl (by id) + source: | + curl https://dev.to/api/users/1 + - lang: Shell + label: curl (by username) + source: | + curl https://dev.to/api/users/by_username?url=ben + + /users/me: + get: + operationId: getUserMe + summary: The authenticated user + description: | + This endpoint allows the client to retrieve information + about the authenticated user + tags: + - users + responses: + "200": + description: A user + content: + application/json: + schema: + $ref: "#/components/schemas/User" + examples: + user-success: + $ref: "#/components/examples/User" + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: "#/components/schemas/APIError" + examples: + error-unauthorized: + $ref: "#/components/examples/ErrorUnauthorized" + security: + - api_key: [] + - oauth2: [] + x-code-samples: + - lang: Shell + label: curl + source: | + curl -H "api-key: API_KEY" https://dev.to/api/users/me + + /videos: + get: + operationId: getArticlesWithVideo + summary: Articles with a video + description: | + This endpoint allows the client to retrieve a list of articles + that are uploaded with a video. + + It will only return published video articles + ordered by descending popularity. + + It supports pagination, each page will contain `24` articles by default. + tags: + - articles + - videos + parameters: + - name: page + in: query + description: Pagination page. + schema: + type: integer + format: int32 + example: 1 + - name: per_page + in: query + description: Page size (defaults to 24 with a maximum of a 1000). + schema: + type: integer + format: int32 + example: 24 + responses: + "200": + description: A list of video articles + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/ArticleVideo" + examples: + articles-success: + $ref: "#/components/examples/ArticleVideo" + x-code-samples: + - lang: Shell + label: curl (all video articles) + source: | + curl https://dev.to/api/videos + /webhooks: get: operationId: getWebhooks @@ -2774,7 +3029,7 @@ paths: description: Id of the webhook schema: type: integer - format: int32 + format: int64 example: 123 responses: "200": @@ -2827,7 +3082,7 @@ paths: description: Id of the webhook schema: type: integer - format: int32 + format: int64 example: 123 responses: "204": diff --git a/docs/contributing_api.md b/docs/contributing_api.md index a1df39cd8..28104cb48 100644 --- a/docs/contributing_api.md +++ b/docs/contributing_api.md @@ -7,6 +7,10 @@ title: Contributing to the API Specification Docs The API v0 is described with the [OpenAPI 3 specification](https://spec.openapis.org/oas/v3.0.3). +Swagger.io has +[great docs](https://swagger.io/docs/specification/basic-structure/) that are +helpful to understand the specification better. + ## Where you can find the spec file We auto-generate the documentation from `api_v0.yml` within the `/docs`