A GraphQL message api written with the Nest framework.
I chose to use the nest framework because for these reasons.
- I am highly familiar with it due to usage in personal projects
- Nest provides significant boiler plate code with a starting point for tests and services
- I wanted to demonstrate my ability to work with GraphQL and NestJS provides an efficient way to declare resolvers with TypeScript annotations
Note: To install the app and its dependencies you must have the latest NodeJS
In the project directory, install the project dependencies using NPM
$ npm installPlease run the app by running the following command
$ npm run startI have created a Docker file for this project. It can be built and run with the following command.
$ docker build -t local . && docker run -p 3000:3000 -it localUnit tests can be run with the commands below
# unit tests
$ npm run test
# run tests with coverage reports
$ npm run test:covThe API is a GraphQL api and so sending requests is a bit different but should still be straight forward. Special libraries exist to facilitate in using a GraphQL API, but they are not required.
Requests can be made from the browser with fetch
fetch('https://localhost:3000/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: `
query testQuery($user: String!) {
user1: user(name: $user){
name
messages {
sender
recipient
message
}
}
}
`,
variables: {
user: "matt",
},
}),
})The easiest way to test the API is by using the GraphiQL Playground which is enabled in the project
Start the project and navigate to http://localhost:3000/graphql in your web browser to open the playground.
In the left panel you can easily draft a query or mutation and send it using the play button.
Messages are sent using the sendMessage mutation.
Sender, recipient, and message are required fields. The return value is the message object that was created which has been appended with the date the message was sent
mutation {
sendMessage(message: {
sender: "matt"
recipient: "michael"
message: "Hello world!"
}){
date
sender
message
recipient
}
}There are multiple ways that messages can be retrieved using this api
Messages for a specific user can be retrieved by sending a query to the messages root Query and
providing a recipient in the where input variable
query getMessagesForJoe {
messages(where: {
recipient: "joe"
}){
sender
message
date
recipient
}
}Messages for a specific user can also be retrieved through the user root Query by requesting the messages field.
All messages for that user will be retrieved. This may be useful if the API is to be included in a federated graph.
By using the name property as a foreign key, the messages property may be appended to the user object.
query getMessagesForJoeV2 {
user(name: "joe"){
name
messages {
sender
message
date
recipient
}
}
}
Messages from a specific user can be retrieved by adding a sender property to the where variable in either case
query getMessagesForJoeFromEric {
messages(where: {
sender: "eric"
recipient: "joe"
}){
sender
message
date
recipient
}
}
query getMessagesForJoeFromEricV2 {
user(name: "joe"){
name
messages(where: {
sender: "eric"
}) {
sender
message
date
recipient
}
}
}
Messages retrieval can be further controlled using the limit and afterDate properties on the where input object.
By default, limit is set to 100 and afterDate is set to 30 days ago. If they are not provided, the api will return the latest 100 messages sent in the last 30 days
query getLastMessageToJoeFromEric {
messages(where: {
sender: "eric"
recipient: "joe"
limit: 1
}){
sender
message
date
recipient
}
}query getLastMessageToJoeFromEricV2 {
user(name: "joe"){
name
messages(where: {
sender: "eric"
limit: 1
}) {
sender
message
date
recipient
}
}
}# Get yesterday's date in JS
#
# var yesterday = new Date();
# yesterday.setDate(yesterday.getDate() - 1);
#
query getMessagesForJoeFromYesterday($yesterday: DateTime!) {
messages(where: {
sender: "eric"
recipient: "joe"
afterDate: $yesterday
}){
sender
message
date
recipient
}
}# Get yesterday's date in JS
#
# var yesterday = new Date();
# yesterday.setDate(yesterday.getDate() - 1);
#
query getMessagesForJoeFromYesterdayV2($yesterday: DateTime!) {
user(name: "joe"){
name
messages(where: {
afterDate: $yesterday
}) {
sender
message
date
recipient
}
}
}