This project is a fullstack application with a React Native app with Apollo Client and an api using Apollo Server and Mongodb. π
This repo contains two projects the api and the app
api
: The backend of the project, Serverapp
: The app, Client
Follow the scripts below to get the project running on your machine. To make local development easier the project is set up to run Mongodb and Apollo in Docker containers.
This will work on Mac and Linux machines and Docker Hyper -V but if you are using WSL on windows 10 you may have connection errors between the containers and the react native app on your device. If you are having this problem it is because WSL is not exposed to the network by default, to fix instead of npm up
run this:
$ docker stop apollo # Only run if you are using WSL
$ Set-Content -Path ".env" -Value "DB_HOST=mongodb://localhost:27017"
# running dev uses nodemon to hot reload
$ npm dev # # Only run if you are using WSL
This stops the container, changes the location where Apollo
is looking for the Mongodb instance, and runs the API using node.
This will allow your React App to connect to your machine instead of the WSL container.
$ git clone https://github.com/Jonathannsegal/graphql_chat.git
# API
$ cd api
$ npm install
# On Windows
$ Set-Content -Path ".env" -Value "DB_HOST=mongodb://mongo:27017"
# On Mac
$ touch ~/.env
$ echo "DB_HOST=mongodb://mongo:27017" >> ~/.inputrc
# If you are having above mentioned connection issues run the script above instead
$ npm up # This will run the docker-compose script
$ cd ..
We need to change the connection strings in app\app.config.js
The values now point to the deployed instance of this repository, to point to the services that we just set up change values to what you see below:
export default ({config}) => {
return Object.assign(config,
{
extra: {
WSHOST: 'ws://localhost:4000/graphql',
HTTPHOST: 'http://localhost:4000/'
}
});
};
Now that our app is pointing to the correct api run this script to start expo bundler and run the app on your phone:
# APP
$ cd app
$ npm dev # This project is using expo, a website will open
# Scan the QR code on a mobile device
The project is deploying automaticly using github actions to Google Cloud App Engine
First go to Google cloud console and create a new App Engine Project, then to deploy and add secrets you need to have gcloud local installed: install, After it is installed run:
# Login and set project
$ gcloud auth login
This project is using github actions and secrets to deploy to App Engine, the guide on how to configure that is here. Because App Engine does not support enviorment variables I choose to go with Google Secrets Manager to store my Mongodb Atlas connection string. Mongodb provides a free cluster for testing you can get that set up by following walkthrough here. Once you have your cluster set up get your connection string and add that to a secret in Secrets Manager by running the following command after changing "Atlas Connection" to your Atlas Connection string.
# Set Secret
$ echo "Atlas Connection" | gcloud secrets create DB_HOST --replication-policy=automatic
Once the secret is set it's time to deploy the project. A App Engine project needs a app.yaml file, this project's file contains:
# We are building from a docker container so we need a custom runtime
runtime: custom
# Flex is better for scalling instances of the api
env: flex
# Settings
manual_scaling:
instances: 1
resources:
cpu: 1
memory_gb: 0.5
disk_size_gb: 10
Make sure that you are in the api directory and then to deploy run:
# Deploy!
$ gcloud app deploy
Type y
when prompted Do you want to continue (Y/n)
y
It will take a few minutes to build the project and deploy it. If everything worked you should see the url where the service was deployed to. Run:
# Deploy!
$ gcloud app browse
To open the deployed api. This will take you to your Graphql-Playground.
The project is using graphql and it is easily testable using the Graphql-Playground. To access locally go to http://localhost:4000/ which is how this project is setup by default, to this project's live api and test out some commands go to https://graphqlchatgcp.uc.r.appspot.com/.
First lets make a user:
mutation {
addUser (
username: "Cool Username"
){
_id
username
}
}
Copy the _id feild
Now that we have a user lets post a message: Paste your user _id feild into the userId feild for the message.
mutation {
addMessage (
text: "Cool Message"
userId: "..."
username: "Cool Username"
){
_id
text
userId
username
}
}
Now that we have have made a user and posted a message lets retrieve that information.
This will show us a list of all users stored in the database.
query {
users {
_id
username
}
}
Now lets look at the messages
query {
messages {
_id
text
userId
username
}
}
This project is also set up with subscriptions using PubSub:
To try this out open two windows of Graphql-Playground,
In the first run
subscription {
messages {
_id
text
userId
username
}
}
Now that we have a subscription running lets post a message:
subscription {
messages {
_id
text
userId
username
}
}
You should see the information update live in the subscription view! π
assets
: Images for the app iconsrc
: Main screens as well as,src\components
: The messages componentsrc\constants
: Graphql queries./App.json
: Configuration for Expo./app.config.js
: constants for connecting to the API
As stated in the Local Development section the app.config.js
file contains the connection strings to the api.
Change the strings to match to the api endpoint that you want to connect to.
export default ({config}) => {
return Object.assign(config,
{
extra: {
WSHOST: 'web socket api string',
HTTPHOST: 'http api string'
}
});
};
The project is using Secrets Manager and to access the value there is an async main method in app\index.js
to change that value to your own secret change the line
// To access your secret change graphqlchatgcp to your project id
const name = 'projects/graphqlchatgcp/secrets/DB_HOST/versions/1';
this should look like:
// To access your secret change graphqlchatgcp to your project id
const name = 'projects/{{ Your Project ID }}/secrets/DB_HOST/versions/1';
To test this on your device download the expo app
Run:
$ cd app
$ npm dev
This opens Metro Bundler which looks like
From here you are able to scan the qr code from the app on Android or use the link on IOS.