This repository has been archived by the owner on Nov 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
78 changed files
with
12,599 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# editorconfig.org | ||
root = true | ||
|
||
[*] | ||
indent_style = space | ||
indent_size = 2 | ||
end_of_line = lf | ||
charset = utf-8 | ||
insert_final_newline = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
# OK GROW! Training | ||
|
||
Welcome to Advanced GraphQL! In order to make the best use of peoples' time, we ask you to **please take the time to set a few things up before the class. NOTE: If your employer-provided laptop uses a proxy, it may block these services. The best solution is to use a personal laptop which has unrestricted access to the internet. If you are blocked on this, please contact us as soon as possible**. | ||
|
||
## For students coming from GraphQL Fundamentals | ||
|
||
You will need one more api ([Apollo Engine](https://engine.apollographql.com/)), but you can start with your .env files from the fundamentals class. | ||
|
||
You can see that we have also made a few changes to the project: | ||
|
||
- The Create React App structure has been "ejected" (we have a webpack config) | ||
- We are therefore able to use .gql files for queries instead of .js | ||
- We have used fragments to standardize query fields between different client GraphQL operations. | ||
- We have split our schema up into multiple files | ||
|
||
These changes form a better foundation for advanced GraphQL patterns. | ||
|
||
## Setup Success looks like this | ||
|
||
You will need to get two dev servers working, one for the GraphQL API, and one for the React UI. | ||
|
||
If the `api` server is running correctly, you will see the following at [localhost:4000](http://localhost:4000): | ||
|
||
![A correctly configured API server](screenshots/graphql_playground_screenshot.png) | ||
|
||
Detailed instructions can be found [here](#API-server-setup) | ||
|
||
If the `ui` server is running correctly, you will see the following at [localhost:3000](http://localhost:3000/). Logging in won't work yet | ||
|
||
![A correctly configured client app](screenshots/ui_screenshot.png) | ||
|
||
Detailed instructions can be found [here](#UI-server-setup) | ||
|
||
## About the Class | ||
|
||
### Versioning | ||
|
||
We’ll use [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) to complete exercises. | ||
|
||
### Code editor | ||
|
||
We recommend [VS Code](https://code.visualstudio.com/) with the following packages installed: | ||
|
||
- ESLint | ||
- One of: | ||
- GraphQL for VSCode (or) | ||
- GraphQL (newer) | ||
- Prettier - Code formatter | ||
|
||
If you prefer to use another editor, please check for corresponding packages. | ||
|
||
### Node.js | ||
|
||
You’ll need Node.js installed. We recommend the use of [NVM](https://nvm.sh). You can also install it from the [official website](https://nodejs.org). **We’ll use Node 8 (LTS).** The packages are not guaranteed to work with other releases. | ||
|
||
Though Node comes with a package manager called npm, we’ll use [Yarn](https://yarnpkg.com), a modern deterministic packager. | ||
|
||
## Prerequisite knowledge | ||
|
||
We will explore all of this thoroughly during the course, but if you are not comfortable with the following concepts, these links are worth a look. | ||
|
||
### JavaScript basics | ||
|
||
We won’t cover basic JS syntax. You should know at least how to write a function. If you don’t, please take this free course on [Codecademy](https://www.codecademy.com). | ||
|
||
### ES2015+ | ||
|
||
Recent tools are making good use of the newest features in ES2015 and even ES2016 and ES2017. The newest JavaScript is a joy to use. If you haven't tried these, we hope you'll enjoy getting to know the new JS: http://es6-features.org/ | ||
|
||
Used in this class | ||
|
||
- modules with import/export | ||
- const and let | ||
- arrow functions | ||
- destructuring, rest and spread operators | ||
- template literals (everywhere, but a special use in GraphQL) | ||
- async/await - APIs and Apollo | ||
- Array.concat() | ||
|
||
### React | ||
|
||
We will be using [React](https://facebook.github.io/react/) to render client components. | ||
|
||
One nice thing about React is that it is close to base JS, so you should be able to follow even if you are new to it. Nevertheless, some understanding of it will be highly useful. We will implement the GraphQL integration with [render props](https://reactjs.org/docs/render-props.html). We'll help you if this is new to you. | ||
|
||
### Nice to have - GraphQL culture | ||
|
||
Some background on GraphQL: “[So what’s this GraphQL thing I keep hearing about?](https://medium.freecodecamp.com/so-whats-this-graphql-thing-i-keep-hearing-about-baf4d36c20cf)” | ||
|
||
We will be using [Apollo](https://www.apollographql.com/docs/) for client and server GraphQL operations. You can get a head start by reviewing the documentation, but we will cover everything you need to know during the class. | ||
|
||
## Questions before the course starts | ||
|
||
Depending on your current level, you can expect to spend up to several hours on this material. It's worth it, and you will get much more from the class. If anything here is confusing or you want to clarify a fine point, please get in touch. We are happy to answer your questions, before, during, and after the class. | ||
|
||
Ping us on Twitter: | ||
|
||
- Robert Dickert - [@rdickert](https://twitter.com/rdickert) | ||
- Paul Dowman - [@pauldowman](https://twitter.com/pauldowman) | ||
|
||
Or email us at [training@okgrow.com](mailto:training@okgrow.com) | ||
|
||
## Code Quality | ||
|
||
We strive to use best practices in this repo, but we prioritize the learning experience where necessary. | ||
|
||
This usually just means a simplified file structure, but this app lacks some safety and security features, so please use your judgment when reusing this code. | ||
|
||
If you have any questions or concerns about specific code, please ask us; we love to talk about code quality. | ||
|
||
## Detailed setup instructions | ||
|
||
### API server setup | ||
|
||
```sh | ||
# make a .env file from the example | ||
cp .env.example .env | ||
``` | ||
|
||
Update the .env file with your api keys: | ||
|
||
- [GOOGLE_API_KEY](https://cloud.google.com/maps-platform) – click "Get Started" and choose Places to enable an API key with `geocoding`. Google will collect billing information, but we will not incur any costs during this training. | ||
- [DARKSKY_API_KEY](https://darksky.net/dev) | ||
- [ENGINE_API_KEY](https://engine.apollographql.com/) | ||
|
||
```sh | ||
# install the dependencies | ||
yarn | ||
|
||
# run the API server | ||
yarn start | ||
``` | ||
|
||
#### Reset the database | ||
|
||
This is not required for setup, but if you end up with a lot of `place`s while developing or your data gets corrupted, you can reset the db to the default setup with: | ||
|
||
```sh | ||
yarn reset-db | ||
``` | ||
|
||
### UI server setup | ||
|
||
> This project was bootstrapped with [Create React App](https://github.com/facebookincubator/create-react-app). | ||
```sh | ||
# make a .env file from the example | ||
cp .env.example .env | ||
``` | ||
|
||
Update the .env file with your api keys: | ||
|
||
- REACT_APP_GOOGLE_API_KEY: use the key you entered in the api folder as GOOGLE_API_KEY | ||
|
||
```sh | ||
# install the dependencies | ||
yarn | ||
|
||
# run the web server | ||
yarn start | ||
``` | ||
|
||
## Troubleshooting | ||
|
||
If you have issues you can't resolve, please contact us before the class if at all possible. If you resolve your problem, please let us know what you did so we can improve this readme. Here are a some pointers: | ||
|
||
- Make sure you are on **Node 8**. Both earlier and later versions may not work as expected. | ||
- MongoDB errors: This app starts MongoDB automatically when you run the api server. If you get MongoDB errors, start by checking your Node version. If it still doesn't work, you can independently install Mongo and run the database with `mongod` before starting the api server. | ||
- external API problems: | ||
- Make sure you set up .env files in both `api/` and `ui/`. You'll need to restart the servers for changes to take effect. | ||
- If Google gives you an authorization error, make sure your Google API key includes `geocoding`, and make a new one if not. | ||
- Make sure your laptop is not blocking outside api calls via a proxy. You may be able to stop the proxy (e.g., in a Vagrant dev setup), but if you can't, you may want to use a personal laptop instead. Contact us if you think this is a blocker for you. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
presets: ['env'], | ||
plugins: [ | ||
'transform-runtime', | ||
'transform-async-generator-functions', | ||
'transform-object-rest-spread', | ||
], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
PORT=8080 | ||
GOOGLE_API_KEY= | ||
DARKSKY_API_KEY= | ||
ENGINE_API_KEY= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"extends": ["prettier"], | ||
"plugins": ["prettier"], | ||
"rules": { | ||
"prettier/prettier": [ | ||
"error", | ||
{ | ||
"singleQuote": true, | ||
"trailingComma": "es5", | ||
"printWidth": 80 | ||
} | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/db | ||
/node_modules | ||
|
||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import dotenv from 'dotenv-safe'; | ||
import nodemon from 'nodemon'; | ||
import fs from 'fs'; | ||
import path from 'path'; | ||
import mongoPrebuilt from 'mongodb-prebuilt'; | ||
import denodeify from 'denodeify'; | ||
|
||
const dbpath = `${__dirname}/db`; | ||
|
||
dotenv.config(); | ||
|
||
const { | ||
PORT = 8080, | ||
MONGO_PORT = parseInt(PORT, 10) + 2, | ||
MONGO_URL | ||
} = process.env; | ||
|
||
// Taken from https://github.com/meteor/meteor/blob/debug-circle-timeout-promise-await/tools/utils/mongo-exit-codes.js | ||
const MONGO_CODES = { | ||
0: { | ||
code: 0, | ||
symbol: 'EXIT_CLEAN', | ||
longText: 'MongoDB exited cleanly' | ||
}, | ||
1: { | ||
code: 1, | ||
// No symbol in the source. This is in src/mongo/base/initializer.cpp. | ||
symbol: 'global-initialization', | ||
longText: 'MongoDB failed global initialization' | ||
}, | ||
2: { | ||
code: 2, | ||
symbol: 'EXIT_BADOPTIONS', | ||
longText: | ||
'MongoDB was started with erroneous or incompatible command line options' | ||
}, | ||
3: { | ||
code: 3, | ||
symbol: 'EXIT_REPLICATION_ERROR', | ||
longText: | ||
'There was an inconsistency between hostnames specified\n' + | ||
'on the command line compared with hostnames stored in local.sources' | ||
}, | ||
4: { | ||
code: 4, | ||
symbol: 'EXIT_NEED_UPGRADE', | ||
longText: 'MongoDB needs to upgrade to use this database' | ||
}, | ||
5: { | ||
code: 5, | ||
symbol: 'EXIT_SHARDING_ERROR', | ||
longText: 'A moveChunk operation failed' | ||
}, | ||
12: { | ||
code: 12, | ||
symbol: 'EXIT_KILL', | ||
longText: 'The MongoDB process was killed, on Windows' | ||
}, | ||
14: { | ||
code: 14, | ||
symbol: 'EXIT_ABRUPT', | ||
longText: 'Unspecified unrecoverable error. Exit was not clean' | ||
}, | ||
20: { | ||
code: 20, | ||
symbol: 'EXIT_NTSERVICE_ERROR', | ||
longText: 'Error managing NT Service on Windows' | ||
}, | ||
45: { | ||
code: 45, | ||
symbol: 'EXIT_FS', | ||
longText: 'MongoDB cannot open or obtain a lock on a file' | ||
}, | ||
47: { | ||
code: 47, | ||
symbol: 'EXIT_CLOCK_SKEW', | ||
longText: 'MongoDB exited due to excess clock skew' | ||
}, | ||
48: { | ||
code: 48, | ||
symbol: 'EXIT_NET_ERROR', | ||
longText: | ||
'MongoDB exited because its port was closed, or was already\n' + | ||
'taken by a previous instance of MongoDB' | ||
}, | ||
100: { | ||
code: 100, | ||
symbol: 'EXIT_UNCAUGHT', | ||
longText: | ||
'MongoDB had an unspecified uncaught exception.\n' + | ||
'This can be caused by MongoDB being unable to write to a local database.\n' + | ||
`Check that you have permissions to write to ${dbpath}. MongoDB does\n` + | ||
'not support filesystems like NFS that do not allow file locking.' | ||
} | ||
}; | ||
|
||
if (!MONGO_URL) { | ||
console.log( | ||
`Creating development MongoDB on mongodb://localhost:${MONGO_PORT}` | ||
); | ||
|
||
if (!fs.existsSync(dbpath)) { | ||
fs.mkdirSync(dbpath); | ||
} | ||
|
||
// Weirdly, this promise never resolves if Mongo starts. | ||
// However, we'll just go ahead and start the node server anyway, | ||
// and if we see an error, we'll quit | ||
denodeify(mongoPrebuilt.start_server.bind(mongoPrebuilt))({ | ||
auto_shutdown: true, | ||
args: { | ||
port: MONGO_PORT, | ||
dbpath | ||
} | ||
}).catch(errorCode => { | ||
const error = MONGO_CODES[errorCode]; | ||
console.error(`Failed to start MongoDB server on port ${MONGO_PORT}`); | ||
console.error( | ||
`Error Code ${errorCode}: ${error ? error.longText : 'Unknown'}` | ||
); | ||
process.exit(1); | ||
}); | ||
} | ||
|
||
nodemon({ | ||
script: path.join('src/server', 'index.js'), | ||
ext: 'js graphql', | ||
exec: 'babel-node' | ||
}).on('restart', () => console.log('Restarting server due to file change\n')); | ||
|
||
// Ensure stopping our parent process will properly kill nodemon's process | ||
// Ala https://www.exratione.com/2013/05/die-child-process-die/ | ||
|
||
// SIGTERM AND SIGINT will trigger the exit event. | ||
process.once('SIGTERM', function() { | ||
process.exit(0); | ||
}); | ||
process.once('SIGINT', function() { | ||
process.exit(0); | ||
}); | ||
// And the exit event shuts down the child. | ||
process.once('exit', function() { | ||
nodemon.emit('SIGINT'); | ||
}); |
Oops, something went wrong.