Add an OpenAPI description and some overrides for debug builds to test locally
The CORS stuff allows for testing against the API with swagger-editor on my machine but is not strictly necessary. The `dredd.yml` is for use with Dredd (`npm i dredd`) and doesn't _currently_ pass muster
This commit is contained in:
parent
43cae8a372
commit
1ce8bee5a8
|
@ -0,0 +1,210 @@
|
|||
---
|
||||
swagger: "2.0"
|
||||
info:
|
||||
description: |
|
||||
Dot dot vote!
|
||||
version: "1.0.0"
|
||||
title: Dot dot vote
|
||||
contact:
|
||||
email: "rtyler+dotdotvote@brokenco.de"
|
||||
license:
|
||||
name: "LGPL v3.0"
|
||||
url: "https://www.gnu.org/licenses/lgpl-3.0.en.html"
|
||||
host: "localhost:8000"
|
||||
basePath: "/api/v1"
|
||||
tags:
|
||||
- name: "poll"
|
||||
description: Poll manipulation APIs
|
||||
externalDocs:
|
||||
description: "Find out more"
|
||||
url: "http://swagger.io"
|
||||
schemes:
|
||||
- "http"
|
||||
- "https"
|
||||
paths:
|
||||
/polls:
|
||||
put:
|
||||
tags:
|
||||
- "poll"
|
||||
summary: "Create a new poll"
|
||||
description: "Create a new poll"
|
||||
operationId: "createPoll"
|
||||
consumes:
|
||||
- "application/json"
|
||||
produces:
|
||||
- "application/json"
|
||||
parameters:
|
||||
- in: "body"
|
||||
name: "body"
|
||||
description: |
|
||||
Insertable Poll object that must be provided in order to actually create the poll.
|
||||
required: true
|
||||
schema:
|
||||
$ref: "#/definitions/InsertablePoll"
|
||||
responses:
|
||||
'201':
|
||||
description: |
|
||||
Poll created successfully
|
||||
schema:
|
||||
type: 'object'
|
||||
properties:
|
||||
poll:
|
||||
type: string
|
||||
description: 'A UUID for the generated poll'
|
||||
example: '8497479a-9f07-4530-9a5c-2824238d5975'
|
||||
"422":
|
||||
description: |
|
||||
Invalid JSON supplied
|
||||
'500':
|
||||
description: |
|
||||
Some server side error has occurred.
|
||||
'/polls/{uuid}':
|
||||
get:
|
||||
tags:
|
||||
- poll
|
||||
summary: 'Fetch the details of the given poll'
|
||||
description: |
|
||||
Access the Poll details and metadata, but _not_ the results
|
||||
parameters:
|
||||
- in: path
|
||||
name: uuid
|
||||
required: true
|
||||
type: string
|
||||
format: uuid
|
||||
|
||||
responses:
|
||||
200:
|
||||
description: Poll found
|
||||
schema:
|
||||
$ref: '#/definitions/PollResponse'
|
||||
400:
|
||||
description: |
|
||||
Either the UUID parameter wasn't provided or it did not parse as a legitimate UUIDv4
|
||||
404:
|
||||
description: |
|
||||
Poll not found
|
||||
'/polls/{uuid}/vote':
|
||||
post:
|
||||
tags:
|
||||
- poll
|
||||
summary: 'Vote in the specified poll'
|
||||
parameters:
|
||||
- in: path
|
||||
name: uuid
|
||||
required: true
|
||||
type: string
|
||||
format: uuid
|
||||
responses:
|
||||
200:
|
||||
description: Vote submitted
|
||||
400:
|
||||
description: |
|
||||
Either the UUID parameter wasn't provided or it did not parse as a legitimate UUIDv4
|
||||
404:
|
||||
description: |
|
||||
Poll not found
|
||||
'/polls/{uuid}/results':
|
||||
get:
|
||||
tags:
|
||||
- poll
|
||||
summary: 'Fetch the results for the specified poll'
|
||||
parameters:
|
||||
- in: path
|
||||
name: uuid
|
||||
required: true
|
||||
type: string
|
||||
format: uuid
|
||||
responses:
|
||||
200:
|
||||
description: Poll found
|
||||
schema:
|
||||
$ref: '#/definitions/PollResults'
|
||||
400:
|
||||
description: |
|
||||
Either the UUID parameter wasn't provided or it did not parse as a legitimate UUIDv4
|
||||
404:
|
||||
description: |
|
||||
Poll not found
|
||||
definitions:
|
||||
PollResponse:
|
||||
type: object
|
||||
properties:
|
||||
poll:
|
||||
$ref: '#/definitions/RawPoll'
|
||||
choices:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/RawChoice'
|
||||
PollResults:
|
||||
type: object
|
||||
properties:
|
||||
poll:
|
||||
$ref: '#/definitions/RawPoll'
|
||||
choices:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/RawChoice'
|
||||
votes:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/RawVote'
|
||||
RawPoll:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: number
|
||||
format: int32
|
||||
uuid:
|
||||
type: string
|
||||
format: uuid
|
||||
title:
|
||||
type: string
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
RawChoice:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: number
|
||||
format: int32
|
||||
poll_id:
|
||||
type: number
|
||||
format: int32
|
||||
details:
|
||||
type: string
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
RawVote:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: number
|
||||
format: int32
|
||||
poll_id:
|
||||
type: number
|
||||
format: int32
|
||||
choice_id:
|
||||
type: number
|
||||
format: int32
|
||||
dots:
|
||||
type: number
|
||||
format: in32
|
||||
voter:
|
||||
type: string
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
InsertablePoll:
|
||||
type: "object"
|
||||
properties:
|
||||
title:
|
||||
type: "string"
|
||||
example: 'My amazing poll!'
|
||||
choices:
|
||||
type: "array"
|
||||
items:
|
||||
type: "string"
|
||||
example: 'Choice 1'
|
|
@ -0,0 +1,32 @@
|
|||
color: true
|
||||
header: true
|
||||
dry-run: null
|
||||
hookfiles: null
|
||||
language: nodejs
|
||||
require: null
|
||||
server: cargo run
|
||||
server-wait: 3
|
||||
init: false
|
||||
custom: {}
|
||||
names: false
|
||||
only: []
|
||||
reporter: []
|
||||
output: []
|
||||
sorted: false
|
||||
user: null
|
||||
inline-errors: false
|
||||
details: false
|
||||
method: []
|
||||
loglevel: warning
|
||||
path: []
|
||||
hooks-worker-timeout: 5000
|
||||
hooks-worker-connect-timeout: 1500
|
||||
hooks-worker-connect-retry: 500
|
||||
hooks-worker-after-connect-wait: 100
|
||||
hooks-worker-term-timeout: 5000
|
||||
hooks-worker-term-retry: 500
|
||||
hooks-worker-handler-host: 127.0.0.1
|
||||
hooks-worker-handler-port: 61321
|
||||
config: ./dredd.yml
|
||||
blueprint: api-description.yml
|
||||
endpoint: 'http://localhost:8000'
|
26
src/main.rs
26
src/main.rs
|
@ -55,6 +55,18 @@ mod dao {
|
|||
}
|
||||
|
||||
impl Poll {
|
||||
/*
|
||||
pub async fn create(title: &str, tx: &mut (impl sqlx::Connection + Copy + sqlx::executor::RefExecutor<'_>)) -> Result<Poll, sqlx::Error> {
|
||||
sqlx::query_as!(Poll,
|
||||
"INSERT INTO polls (title, uuid) VALUES ($1, $2) RETURNING *",
|
||||
title,
|
||||
Uuid::new_v4()
|
||||
)
|
||||
.fetch_one(tx)
|
||||
.await
|
||||
}
|
||||
*/
|
||||
|
||||
pub async fn from_uuid(uuid: uuid::Uuid, db: &crate::DbPool) -> Result<Poll, sqlx::Error> {
|
||||
sqlx::query_as!(Poll, "SELECT * FROM polls WHERE uuid = $1", uuid)
|
||||
.fetch_one(db)
|
||||
|
@ -343,6 +355,20 @@ async fn main() -> Result<(), std::io::Error> {
|
|||
Ok(db) => {
|
||||
let state = AppState { db };
|
||||
let mut app = tide::with_state(state);
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
info!("Enabling a very liberal CORS policy for debug purposes");
|
||||
use tide::security::{CorsMiddleware, Origin};
|
||||
let cors = CorsMiddleware::new()
|
||||
.allow_methods("GET, POST, PUT, OPTIONS".parse::<tide::http::headers::HeaderValue>().unwrap())
|
||||
.allow_origin(Origin::from("*"))
|
||||
.allow_credentials(false);
|
||||
|
||||
app.with(cors);
|
||||
}
|
||||
|
||||
debug!("Configuring routes");
|
||||
app.at("/").get(routes::index);
|
||||
app.at("/api/v1/polls").put(routes::polls::create);
|
||||
app.at("/api/v1/polls/:uuid").get(routes::polls::get);
|
||||
|
|
Loading…
Reference in New Issue