From 241d7688cb6d5995a2f63d5824846f2968dd21d8 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon <67381+philsturgeon@users.noreply.github.com> Date: Tue, 2 Jan 2024 14:01:06 +0000 Subject: [PATCH] rails code first done, now for design first --- app/controllers/widgets_controller.rb | 8 +- spec/requests/widgets_spec.rb | 115 +++++++++++++++++--------- swagger/v1/swagger.yaml | 80 +++++++++++++++--- 3 files changed, 150 insertions(+), 53 deletions(-) diff --git a/app/controllers/widgets_controller.rb b/app/controllers/widgets_controller.rb index 6ce04f5..df193d5 100644 --- a/app/controllers/widgets_controller.rb +++ b/app/controllers/widgets_controller.rb @@ -5,12 +5,16 @@ class WidgetsController < ApplicationController def index @widgets = Widget.all - render json: @widgets + if stale?(@posts) + render json: @widgets + end end # GET /widgets/1 def show - render json: @widget + if stale?(@posts) + render json: @widget + end end # POST /widgets diff --git a/spec/requests/widgets_spec.rb b/spec/requests/widgets_spec.rb index 9e78b3d..7105ce5 100644 --- a/spec/requests/widgets_spec.rb +++ b/spec/requests/widgets_spec.rb @@ -4,43 +4,67 @@ path '/widgets' do - get('list widgets') do - response(200, 'successful') do + get 'list widgets' do + produces 'application/json' - after do |example| - example.metadata[:response][:content] = { - 'application/json' => { - example: JSON.parse(response.body, symbolize_names: true) + response 200, 'successful' do + header 'Cache-Control', schema: { type: :string }, description: 'This header declares the cacheability of the content so you can skip repeating requests.' + + schema type: 'array', + items: { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + example: '123e4567-e89b-12d3-a456-426614174000', + }, + title: { + type: 'string', + example: 'Goblin Staff of Sparks', + }, + created_at: { + type: 'string', + format: 'date-time', + }, + updated_at: { + type: 'string', + format: 'date-time', + }, } } - end - run_test! - end - end - post('create widget') do - response(200, 'successful') do - - after do |example| - example.metadata[:response][:content] = { - 'application/json' => { - example: JSON.parse(response.body, symbolize_names: true) - } + example 'application/json', :example_key, [ + { + id: 1, + title: 'Goblin Staff of Sparks', } - end + ] + run_test! + end + + response 429, 'too many requests' do + header 'X-Rate-Limit-Limit', schema: { type: :integer }, description: 'The number of allowed requests in the current period' + header 'X-Rate-Limit-Remaining', schema: { type: :integer }, description: 'The number of remaining requests in the current period' + header 'X-Rate-Limit-Reset', schema: { type: :integer }, description: 'The number of seconds left in the current period' + run_test! end end - end - path '/widgets/{id}' do - # You'll want to customize the parameter types... - parameter name: 'id', in: :path, type: :string, description: 'id' + post 'create widget' do + consumes 'application/json' + produces 'application/json' - get('show widget') do - response(200, 'successful') do - let(:id) { '123' } + parameter name: :widget, in: :body, schema: { + type: :object, + properties: { + title: { type: :string } + }, + required: %w[title] + } + response 200, 'successful' do after do |example| example.metadata[:response][:content] = { 'application/json' => { @@ -50,25 +74,32 @@ end run_test! end - end - - patch('update widget') do - response(200, 'successful') do - let(:id) { '123' } - after do |example| - example.metadata[:response][:content] = { - 'application/json' => { - example: JSON.parse(response.body, symbolize_names: true) + response 422, 'unprocessable entity' do + schema type: 'object', + properties: { + errors: { + type: 'array', + items: { + type: 'object', + properties: { + title: { type: 'string' }, + detail: { type: 'string' }, + code: { type: 'string' }, + } + } } } - end run_test! end end + end - put('update widget') do - response(200, 'successful') do + path '/widgets/{id}' do + parameter name: 'id', in: :path, type: :string, description: 'The unique identifier of a widget.' + + get('show widget') do + response 200, 'successful' do let(:id) { '123' } after do |example| @@ -82,8 +113,8 @@ end end - delete('delete widget') do - response(200, 'successful') do + put('update widget') do + response 200, 'successful' do let(:id) { '123' } after do |example| @@ -95,6 +126,10 @@ end run_test! end + + response 422, 'unprocessable entity' do + end end + end end diff --git a/swagger/v1/swagger.yaml b/swagger/v1/swagger.yaml index f7c5f25..9e4e73a 100644 --- a/swagger/v1/swagger.yaml +++ b/swagger/v1/swagger.yaml @@ -7,19 +7,87 @@ paths: "/widgets": get: summary: list widgets + parameters: [] responses: '200': description: successful + headers: + Cache-Control: + schema: + type: string + description: This header declares the cacheability of the content so + you can skip repeating requests. + content: + application/json: + examples: + example_key: + value: + - id: 1 + title: Goblin Staff of Sparks + schema: + type: object + properties: + errors: + type: array + items: + type: object + properties: + id: + type: string + format: uuid + example: 123e4567-e89b-12d3-a456-426614174000 + title: + type: string + example: Goblin Staff of Sparks + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + '429': + description: too many requests + headers: + X-Rate-Limit-Limit: + schema: + type: integer + description: The number of allowed requests in the current period + X-Rate-Limit-Remaining: + schema: + type: integer + description: The number of remaining requests in the current period + X-Rate-Limit-Reset: + schema: + type: integer + description: The number of seconds left in the current period post: summary: create widget responses: '200': description: successful + '422': + description: unprocessable entity + content: + application/json: + schema: + type: object + properties: + errors: + type: array + items: + type: object + properties: + title: + type: string + detail: + type: string + code: + type: string "/widgets/{id}": parameters: - name: id in: path - description: id + description: The unique identifier of a widget. required: true schema: type: string @@ -28,21 +96,11 @@ paths: responses: '200': description: successful - patch: - summary: update widget - responses: - '200': - description: successful put: summary: update widget responses: '200': description: successful - delete: - summary: delete widget - responses: - '200': - description: successful servers: - url: https://{defaultHost} variables: