This is a Rails project that demonstrates use of rswag
to build REST API with autogenerated Swagger or OpenAPI specification.
The Swagger specification is available at /swagger/v1/swagger.yaml.
- Docker (and
docker-compose
) - Ruby 1.6.4+
- Rails 6.0+
- Node 12.16+
First clone this repository onto your local workstation:
$ git clone https://github.com/aisrael/surveyor.git
$ cd surveyor
Bring up the test database using docker-compose
:
$ docker-compose up -d
Creating network "surveyor_default" with the default driver
Creating surveyor_postgres_1 ... done
Create the test databases:
$ rails db:create db:migrate db:seed
Database 'surveyor_development' already exists
Created database 'surveyor_test'
== 20200401043703 CreateRespondents: migrating ================================
-- create_table(:respondents)
-> 0.0121s
== 20200401043703 CreateRespondents: migrated (0.0121s) =======================
== 20200401054813 CreateQuestions: migrating ==================================
-- create_table(:questions)
-> 0.0098s
== 20200401054813 CreateQuestions: migrated (0.0099s) =========================
== 20200401055617 CreateResponses: migrating ==================================
-- create_table(:responses)
-> 0.0097s
== 20200401055617 CreateResponses: migrated (0.0098s) =========================
Bring up the Rails server:
$ rails server
rails server
=> Booting Puma
=> Rails 6.0.2.2 application starting in development
=> Run `rails server --help` for more startup options
Puma starting in single mode...
* Version 4.3.3 (ruby 2.6.4-p104), codename: Mysterious Traveller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://127.0.0.1:3000
* Listening on tcp://[::1]:3000
Use Ctrl-C to stop
At this point, you should be able to make requests to http://localhost:3000
.
$ curl -X POST http://localhost:3000/api/v1/responses -H 'Content-Type: application/json' -d '{"respondentIdentifier": "00001", "responses": [{"questionId": 1, "body": 4}, {"questionId": 2, "body": "Unclear expectations"}]}'
Should return:
{
"data": [
{
"id": 1,
"respondentIdentifier": "00001",
"questionId": 1,
"body": 4
},
{
"id": 2,
"respondentIdentifier": "00001",
"questionId": 2,
"body": "Unclear expectations"
}
]
}
Trying to submit another set of responses for the same respondentIdentifier gives an error:
$ curl -X POST http://localhost:3000/api/v1/responses -H 'Content-Type: application/json' -d '{"respondentIdentifier": "00001", "responses": [{"questionId": 1, "body": 4}, {"questionId": 2, "body": "Unclear expectations"}]}'
{"errors":[{"status":400,"title":"Respondent already submitted response(s)"}]}
Let's add another set of responses for a different respondent
$ curl -X POST http://localhost:3000/api/v1/responses -H 'Content-Type: application/json' -d '{"respondentIdentifier": "00002", "responses": [{"questionId": 1, "body": 3}, {"questionId": 2, "body": "Noisy workspace"}]}'
{
"data": [
{
"id": 3,
"respondentIdentifier": "00002",
"questionId": 1,
"body": 3
},
{
"id": 4,
"respondentIdentifier": "00002",
"questionId": 2,
"body": "Noisy workspace"
}
]
}
$ curl http://localhost:3000/api/v1/responses
Should return
{
"responses": [
{
"questionId": 1,
"body": 4
},
{
"questionId": 2,
"body": "Unclear expectations"
},
{
"questionId": 1,
"body": 3
},
{
"questionId": 2,
"body": "Noisy workspace"
}
]
}
$ curl http://localhost:3000/api/v1/averages
Should return
{
"questionAverages": [
{
"questionId": 1,
"averageScore": 3.5
}
]
}
$ curl http://localhost:3000/api/v1/scored-question-distributions
Should return
{
"scored_question_distributions": [
{
"questionId": 1,
"responseFrequencies": [
{
"score": 1,
"frequency": 0
},
{
"score": 2,
"frequency": 0
},
{
"score": 3,
"frequency": 1
},
{
"score": 4,
"frequency": 1
},
{
"score": 5,
"frequency": 0
}
]
},
{
"questionId": 3,
"responseFrequencies": [
{
"score": 1,
"frequency": 0
},
{
"score": 2,
"frequency": 0
},
{
"score": 3,
"frequency": 0
},
{
"score": 4,
"frequency": 0
},
{
"score": 5,
"frequency": 0
}
]
},
{
"questionId": 4,
"responseFrequencies": [
{
"score": 1,
"frequency": 0
},
{
"score": 2,
"frequency": 0
},
{
"score": 3,
"frequency": 0
},
{
"score": 4,
"frequency": 0
},
{
"score": 5,
"frequency": 0
}
]
},
{
"questionId": 5,
"responseFrequencies": [
{
"score": 1,
"frequency": 0
},
{
"score": 2,
"frequency": 0
},
{
"score": 3,
"frequency": 0
},
{
"score": 4,
"frequency": 0
},
{
"score": 5,
"frequency": 0
}
]
}
]
}
$ curl http://localhost:3000/api/v1/profile-segment-scores-by-gender
Should return
{
"profileSegmentScores": [
{
"segment": {
"gender": "Female"
},
"questionAverages": [
{
"questionId": 1,
"averageScore": 4
}
]
},
{
"segment": {
"gender": "Male"
},
"questionAverages": [
{
"questionId": 1,
"averageScore": 3
}
]
}
]
}
$ docker build -t aisrael/surveyor .
Sending build context to Docker daemon 88.14MB
Step 1/14 : FROM ruby:2.6.4
---> 121862ceb25f
.
.
.
If you simply want to run the stack without even building anything, aisrael/surveyor
is available for download from [Docker Hub]
$ docker-compose -f docker-compose-prod.yml up -d
Don't forget to initialize the database if you haven't done so:
$ rails db:migrate db:seed