A GraphQL based API for the eq-author application.
Environment variables can be used to configure various aspects of the API. In most cases sensible defaults have been selected.
Tip
If you decide to run the Author API directly using
yarn
you will need to ensure that a suitable database instance is running and configure the associated database environment variables appropriately.Running using
docker-compose
will ensure that a suitable postgres instance is started. So there is no need to configure the environment variables.
Name | Description | Required |
---|---|---|
RUNNER_SESSION_URL |
Authentication URL for survey runner | Yes |
PUBLISHER_URL |
URL that produces valid survey runner JSON | Yes |
DB_CONNECTION_URI |
Connection string for database | Yes |
SECRETS_S3_BUCKET |
Name of S3 bucket where secrets are stored | No |
KEYS_FILE |
Name of the keys file to use inside the bucket | No |
EQ_AUTHOR_API_VERSION |
The current Author API version. This is what gets reported on the /status endpoint | No |
PORT |
The port which express listens on (defaults to 4000 ). |
No |
NODE_ENV |
Sets the environment the code is running in | No |
To build and run the Author GraphQL API inside a docker container, ensure that Docker is installed for your platform, navigate to the project directory, then run:
Build the docker image (1st time run):
docker-compose build
docker-compose up
Once the containers are running you should be able to navigate to http://localhost:4000/graphiql and begin exploring the eQ Author GraphQL API.
Changes to the application should hot reload via nodemon
.
There is no concrete Page
type in the GraphQL schema. Instead we use a Page
interface, which other types implement e.g. QuestionPage
and InterstitialPage
.
To query all pages, and request different fields depending on the type, use inline fragments:
query {
getQuestionnaire(id: 1) {
questionnaire {
sections {
pages {
id,
# inline fragment for `QuestionPage` type
... on QuestionPage {
guidance,
answers {
id,
label
}
},
# For purposes of example only. `InterstitialPage` doesn't exist yet
... on InterstitialPage { # doesn't exist yet
someField
}
}
}
}
}
}
There are queries and example data in the fixtures folder. These can be used with graphiql to manually build up a questionnaire.
First start app using Docker.
yarn knex -- migrate:make name_of_migration
Where name_of_migration
is the name you wish to use. e.g. create_questionnaires_table
docker-compose exec web yarn knex -- migrate:latest
docker-compose exec web yarn knex -- migrate:rollback
yarn test
will start a single run of unit and integration tests.
yarn test --watch
will start unit and integration tests in watch mode.
Follow this guide to enable debugging through VS Code.
Use this config for VS Code, rather than what is detailed in the guide. This will attach to the running docker container:
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Container",
"type": "node",
"request": "attach",
"port": 5858,
"address": "localhost",
"restart": true,
"sourceMaps": false,
"localRoot": "${workspaceRoot}",
"remoteRoot": "/app",
"protocol": "inspector"
}
]
}
Add the following to your launch.json
configuration:
{
"name": "Attach by Process ID",
"type": "node",
"request": "attach",
"processId": "${command:PickProcess}"
}
Then start your tests as described above. You can now start a debugging session, and pick the jest process to attach to.
There is a dev only endpoint exposed in the dev environment to be able to import questionnaires from other environments.
- Run the following query against the environment to retrieve the questionnaire. You need to provide the id as well. (You could use https://github.com/skevy/graphiql-app)
fragment answerFragment on Answer {
id
type
label
description
guidance
properties
qCode
...on BasicAnswer{
validation{
...on NumberValidation{
minValue{
id
inclusive
enabled
custom
}
maxValue{
id
inclusive
enabled
custom
entityType
previousAnswer {
id
}
}
}
...on DateValidation{
earliestDate{
id
enabled
custom
offset {
value
unit
}
relativePosition
}
latestDate{
id
enabled
custom
offset {
value
unit
}
relativePosition
}
}
}
}
...on CompositeAnswer{
childAnswers{
id
label
}
}
}
fragment optionFragment on Option {
id
label
description
value
qCode
}
fragment destinationFragment on RoutingDestination {
... on LogicalDestination {
__typename
logicalDestination
}
... on AbsoluteDestination {
__typename
absoluteDestination {
... on QuestionPage {
id
__typename
}
... on Section {
id
__typename
}
}
}
}
fragment metadataFragment on Metadata {
id
key
type
}
query GetQuestionnaire($questionnaireId: ID!) {
questionnaire(id: $questionnaireId) {
id
title
description
theme
legalBasis
navigation
surveyId
summary
metadata {
...metadataFragment
}
sections {
id
alias
title
description
pages {
... on QuestionPage {
id
alias
title
description
guidance
pageType
routingRuleSet {
id
else {
...destinationFragment
}
routingRules {
id
operation
goto {
...destinationFragment
}
conditions {
id
comparator
answer {
id
type
... on MultipleChoiceAnswer {
options {
id
label
}
other {
option {
id
label
}
}
}
}
routingValue {
... on IDArrayValue {
value
}
... on NumberValue {
numberValue
}
}
}
}
}
answers {
...answerFragment
... on MultipleChoiceAnswer {
options {
...optionFragment
}
mutuallyExclusiveOption {
...optionFragment
}
other {
option {
...optionFragment
}
answer {
...answerFragment
}
}
}
}
}
}
}
}
}
1.POST
the result to /import
. (You could use https://www.getpostman.com/)
- The questionnaire should be there.