This is a demonstration project in Golang that provides an API for Tests and Questionnaires. The tests can be graded
or ungraded with various marking types, please refer to the grading section below.
The limitations on questions and answer options are superficial and are being enforced to demonstrate data validation. For details on the structure of the JSON requests and responses to the various endpoints, please see the REST API section below.
Encryption is vital to help safeguard against theft of login credentials and JSON Web Tokens.
In a production environment, TLS would be the only HTTP protocol over which the API endpoints would be exposed. Setting
up the TLS/SSL certificated for a Dockerized demonstration environment is unnecessary and complicates the tester's
experience.
Other methods like envelope encryption of payloads add an extra layer of security, but these add an excessive overhead for the use case and workloads here.
This demonstration environment will launch both the HTTP REST as well as the GraphQL over HTTP endpoints. This is
unsuitable for a production environment.
Ideally, each of these protocol endpoints would be exposed in its own clusters with auto-scaling, load balancing, and across availability zones.
TODO: There are a number of items that I will complete as time permits:
- REST API
score/statsresponse pagination: The response to a stats request could contain far too many records to send back in a single request and must be paginated. - Denormalize the
responsestable by adding the quizAuthorwith eachresponserow. This will allow queries requesting statistics to merely make calls to theresponsetable. It should then be possible to check authorization using the returned rows. - Redis Cache: To improve the performance of the API, published tests should be cached with an eager write to cache, and lazy loading to the cache on misses.
- GraphQL: Essential for performance on bandwidth restricted connections.
- GraphQL Depth Limits and Complexity: Maximum depth and complexity must be added for security to help mitigate against malicious requests.
Configuration information for the logger can be found in the logger package.
Information regarding authentication configurations can be found in the auth package.
Responses can be graded or ungraded. Details on the grading schemes can be viewed from the grading package.
Information on how to configure the Apache Cassandra connection can be found in the cassandra package.
Details on the scheme used as well as the design and technical decisions taken can be found in the
model_cassandra package.
A docker-compose file is provided to bring up the necessary services, including a Cassandra single-node cluster. The
keyspace and schema will need to be deployed to the cluster manually. CQL statements to achieve this are located in the
model_cassandra package.
For details on migrating the database schema please see the Cassandra Schema Migration and Setup section.
Information on how to configure the Redis connection can be found in the redis package.
Details on the design and technical decisions taken can also be found in the redis package.
A docker-compose file is provided to bring up the necessary services, including a minimal Redis three-node cluster. Redis requires a minimum of three master and three slave nodes for Redis to run in Cluster mode.
Details on the HTTP endpoints can be found in their respective packages below.
The HTTP endpoint details are located in the http_rest package. The model used for REST API calls can
be found in the model_http.
To review the REST API request and response formats please see the readme in the http_handlers
package. The REST API server does also provide a Swagger UI to examine and test the API calls with details on request
formats.
The Swagger UI can be accessed using the provided default configurations through http://localhost:44243/swagger/index.html.
GraphQL has been exposed through an HTTP endpoint graphql package. The schema for the GraphQL queries
and mutations can be found in model_http.
To review the GraphQL API request and response formats please see the readme in the graphql_resolvers
package. The GraphQL server does also provide a Playground to examine and test the API calls with details on request
formats.
The Playground can be accessed using the provided default configurations through http://localhost:44255/api/graphql/v1/playground.
Please provide the ARCH= variable with linux or darwin as needed.
Build
make build ARCH=linuxClean
make cleanTo build the container for deployment in a Kubernetes cluster please run the docker build command
with the required parameters. Please also review the configuration files in the configs
folder and appropriately adjust the ports exposed in the container.
There are port configurations to expose the HTTP REST and GraphQL endpoints. They can be configured
from inside the Dockerfile and must match the config .yaml files. To expose them, please see the
-P
Docker flag.
When testing using docker compose on a local machine you may use the ifconfig to obtain your Host IP:
ifconfig | grep 'inet 192'To spin-up the Cassandra and Redis containers please use the commands below.
Create containers:
docker compose up -dDestroy containers:
docker compose downList Containers and Check Health:
docker psGet IP Addresses:
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' cassandraCassandra:
- Username :
admin - Password :
root - Keyspace:
mcq_platform
Redis:
- Password :
root - Database:
0, the default database - Ports:
6379,6380,6381,6382,6383,6384