This solution uses PosgreSQL for persistence of data.
- Express powered Apollo Server
- PostgreSQL connectivity via Sequelize
- Multiple queries and mutations
- Subscriptions for real-time communication
- PostgreSQL linked resolvers
- Schema documentation via GraphiQL
- Custom validation and error handling
- User registration and token based authentication
- User authorisation via resolver middleware
- Custom scalars
- Cursor-based pagination
- E2E testing
- Batching and caching
- Deployed to Heroku
As PostgreSQL maintains the persistence of data, you will need to create a .env
file in order to connect to your database.
The .env
file should look something like this:
DATABASE=postgres
TEST_DATABASE=postgres_test
DATABASE_USER=postgres
DATABASE_PASSWORD=postgres
SECRET=myverysecuresecretphrase
and must be placed in the root of this repository.
* src/
* node_modules/
.babelrc
----------- .env -----------
.gitattributes
.gitignore
README.md
package-lock.json
package.json
NOTE: Declaring the variable
TEST_DATABASE
will purge all of your existing records and seed your database with new, fresh data on server restart.
NOTE: A
secret
is passed to all resolver functions. Some of these queries and/ or mutations require asecret
to be defined. It can be added as aSECRET
parameter in your.env
file - to be used as an environment variable via thedotenv
dependency. See the Prerequisites section for more info.
{
users {
id
username
email
messages {
id
text
createdAt
}
}
}
{
user(id: 4) {
id
username
email
}
}
mutation {
signUp(username: "TestUser", email: "user@email.com", password: "password123") {
token
}
}
mutation {
signIn(login: "TestUser", password: "password123") {
token
}
}
{
me {
id
username
email
messages {
id
text
createdAt
}
}
}
NOTE: To use this mutation, the user is required to
signIn
with an account that has therole
ofADMIN
.
mutation {
deleteUser(id: "2")
}
NOTE: To use this mutation, the user is required to
signIn
with a valid account. It will update this user's username.
mutation {
updateUser(username: "jappleseed") {
id
username
email
}
}
NOTE: This particular example uses cursor based pagination on the
createdAt
field. It will retrieve the earliest created messages.
{
messages(limit: 2) {
edges {
id
text
createdAt
}
pageInfo {
hasNextPage
endCursor
}
}
messages(limit: 1, cursor: "RnJpIFNlcCAwNiAyMDE5IDEyOjM0OjE5IEdNVCswMTAwIChCcml0aXNoIFN1bW1lciBUaW1lKQ==") {
edges {
id
text
createdAt
}
pageInfo {
hasNextPage
endCursor
}
}
}
{
message(id: "2") {
id
text
createdAt
user {
id
username
email
}
}
}
NOTE: At the moment, this mutation requires a 'me'
User
object to exit insrc/index.js
- as aUser
must exist for aMessage
object to be created.
mutation {
createMessage(text: "Cake") {
id
text
createdAt
}
}
mutation {
deleteMessage(id: "4")
}
subscription {
messageCreated {
message {
id
text
createdAt
user {
id
username
}
}
}
}
Install dependencies:
npm i
Start server:
NOTE: Make sure your PostgreSQL server is running before you start the application.
npm start
Access GraphiQL at: http://localhost:8000/graphiql
NOTE: Make sure your PostgreSQL server is running before you start testing, otherwise the tests will fail.
All tests can be found in the src/tests
folder.
They can be executed using:
npm test