Skip to content
This repository was archived by the owner on Oct 23, 2018. It is now read-only.

[WIP] Adds minimal boilerplate #72

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

**Select a boilerplate and follow the instructions in the belonging README to get started:**

- `minimal` (_coming soon_): Minimal boilerplate with basic "Hello World" functionality
- [`minimal`](./minimal): Minimal boilerplate with basic "Hello world" functionality
- [`basic`](./basic): Basic boilerplate based on a simple data model and with a GraphQL database
- `advanced` (_coming soon_): Advanced boilerplate with a GraphQL database, authentication and realtime subscriptions

Expand Down
8 changes: 8 additions & 0 deletions minimal/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"presets": ["babel-preset-expo"],
"env": {
"development": {
"plugins": ["transform-react-jsx-source"]
}
}
}
3 changes: 3 additions & 0 deletions minimal/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
.expo/
npm-debug.*
28 changes: 28 additions & 0 deletions minimal/.install/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const fs = require('fs')
const {
replaceInFiles,
deploy,
writeEnv,
getInfo,
} = require('graphql-boilerplate-install')

const path = require('path')

module.exports = async ({ project, projectDir }) => {
const templateName = 'graphql-boilerplate'

replaceInFiles(
['server/index.js', 'server/package.json'],
templateName,
project,
)

console.log(`\
Next steps:
1. Change directory: \`cd ${projectDir}/server\`
2. Start local server: \`yarn start\` (you can now open a Playground at http://localhost:4000)
3. Change directory: \`cd ..\`
4. Start React app: \`yarn start\`
5. Open browser: http://localhost:3000
`)
}
7 changes: 7 additions & 0 deletions minimal/.install/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "install",
"version": "0.0.0",
"devDependencies": {
"graphql-boilerplate-install": "0.1.6"
}
}
100 changes: 100 additions & 0 deletions minimal/.install/yarn.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


commander@^2.9.0:
version "2.12.2"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555"

[email protected], cross-spawn@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
dependencies:
lru-cache "^4.0.1"
shebang-command "^1.2.0"
which "^1.2.9"

[email protected]:
version "0.1.6"
resolved "https://registry.yarnpkg.com/graphql-boilerplate-install/-/graphql-boilerplate-install-0.1.6.tgz#7e90219baac8b2f202eef68c4104c1154652eaa3"
dependencies:
cross-spawn "5.1.0"
npm-run "4.1.2"

isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"

lru-cache@^4.0.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55"
dependencies:
pseudomap "^1.0.2"
yallist "^2.1.2"

minimist@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"

npm-path@^2.0.2, npm-path@^2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.4.tgz#c641347a5ff9d6a09e4d9bce5580c4f505278e64"
dependencies:
which "^1.2.10"

[email protected]:
version "4.1.2"
resolved "https://registry.yarnpkg.com/npm-run/-/npm-run-4.1.2.tgz#1030e1ec56908c89fcc3fa366d03a2c2ba98eb99"
dependencies:
cross-spawn "^5.1.0"
minimist "^1.2.0"
npm-path "^2.0.3"
npm-which "^3.0.1"
serializerr "^1.0.3"
sync-exec "^0.6.2"

npm-which@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa"
dependencies:
commander "^2.9.0"
npm-path "^2.0.2"
which "^1.2.10"

protochain@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/protochain/-/protochain-1.0.5.tgz#991c407e99de264aadf8f81504b5e7faf7bfa260"

pseudomap@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"

serializerr@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/serializerr/-/serializerr-1.0.3.tgz#12d4c5aa1c3ffb8f6d1dc5f395aa9455569c3f91"
dependencies:
protochain "^1.0.5"

shebang-command@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
dependencies:
shebang-regex "^1.0.0"

shebang-regex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"

sync-exec@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/sync-exec/-/sync-exec-0.6.2.tgz#717d22cc53f0ce1def5594362f3a89a2ebb91105"

which@^1.2.10, which@^1.2.9:
version "1.3.0"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"
dependencies:
isexe "^2.0.0"

yallist@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
1 change: 1 addition & 0 deletions minimal/.watchmanconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
21 changes: 21 additions & 0 deletions minimal/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import { ApolloProvider } from 'react-apollo';
import { ApolloClient, HttpLink, InMemoryCache } from 'apollo-client-preset';
import Home from './Home';

const httpLink = new HttpLink({ uri: 'http://localhost:4000' });

const client = new ApolloClient({
link: httpLink,
cache: new InMemoryCache()
});

export default class App extends React.Component {
render() {
return (
<ApolloProvider client={client}>
<Home />
</ApolloProvider>
);
}
}
9 changes: 9 additions & 0 deletions minimal/App.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react';
import App from './App';

import renderer from 'react-test-renderer';

it('renders without crashing', () => {
const rendered = renderer.create(<App />).toJSON();
expect(rendered).toBeTruthy();
});
39 changes: 39 additions & 0 deletions minimal/Home.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';

class Home extends React.Component {
render() {
if (this.props.helloQuery.loading)
return (
<View style={styles.container}>
<Text>Loading...</Text>
</View>
);

return (
<View style={styles.container}>
<Text>{this.props.helloQuery.hello}</Text>
</View>
);
}
}

const styles = StyleSheet.create({
container: {
alignItems: 'center',
flex: 1,
justifyContent: 'center'
}
});

const HELLO_QUERY = gql`
query HelloQuery {
hello
}
`;

export default graphql(HELLO_QUERY, {
name: 'helloQuery'
})(Home);
104 changes: 104 additions & 0 deletions minimal/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@

# react-native-apollo-basic

🚀 Basic starter code for a mobile app based on React Native, GraphQL & Apollo Client.

![](https://imgur.com/LG6r1q1.png)

## TODO

- [ ] Fix runtime issue
- [ ] Enable in [https://github.com/graphql-cli/graphql-cli/blob/master/src/cmds/create/boilerplates.ts](https://github.com/graphql-cli/graphql-cli/blob/master/src/cmds/create/boilerplates.ts)

> **PRs are very welcome** 🙏

## Technologies

* **Frontend**
* [React Native](https://facebook.github.io/react-native/): JavaScript framework for building native mobile apps with [React](https://facebook.github.io/react/)
* [Apollo Client](https://github.com/apollographql/apollo-client): Fully-featured, production ready caching GraphQL client
* **Backend**
* [Graphcool](https://www.graph.cool): Powerful GraphQL database
* [`graphql-yoga`](https://github.com/graphcool/graphql-yoga/): Fully-featured GraphQL server with focus on easy setup, performance & great developer experience
* [`graphcool-binding`](https://github.com/graphcool/graphcool-binding): GraphQL binding for Graphcool services

## Requirements

You need to have the following things installed:

* [Expo](https://expo.io/)
* Node 8+
* Graphcool CLI: `npm i -g graphcool@beta`
* GraphQL CLI: `npm i -g graphql-cli`
* GraphQL Playground desktop app (optional): [Download](https://github.com/graphcool/graphql-playground/releases)

## Getting started

```sh
# Bootstrap GraphQL server in directory `my-app`, based on `react-fullstack-basic` boilerplate
graphql create my-app --boilerplate react-native-basic

# Navigate into the new project's `server` directory
cd my-app/server

# Deploy the Graphcool database & start the server (runs on http://localhost:4000)
yarn start

# Navigate back into the project's root directory and launch the React app
cd ..
yarn run ios # open with iOS simulator
# yarn run android # open with Android emulator
# yarn start # open using the Expo app on your phone (does not work when server is deployed locally)
```

<details>

<summary>Alternative: Clone repo</summary>

```sh
TODO
```

</details>

## Docs

### Project structure

#### `/server`

- [`.graphqlconfig.yml`](./server/.graphqlconfig.yml) GraphQL configuration file containing the endpoints and schema configuration. Used by the [`graphql-cli`](https://github.com/graphcool/graphql-cli) and the [GraphQL Playground](https://github.com/graphcool/graphql-playground). See [`graphql-config`](https://github.com/graphcool/graphql-config) for more information.
- [`graphcool.yml`](./server/graphcool.yml): The root configuration file for your database service ([documentation](https://www.graph.cool/docs/1.0/reference/graphcool.yml/overview-and-example-foatho8aip)).

#### `/server/database`

- [`database/datamodel.graphql`](./server/database/datamodel.graphql) contains the data model that you define for the project (written in [SDL](https://blog.graph.cool/graphql-sdl-schema-definition-language-6755bcb9ce51)).
- [`database/schema.generated.graphql`](./server/database/schema.generated.graphql) defines the **database schema**. It contains the definition of the CRUD API for the types in your data model and is generated based on your `datamodel.graphql`. **You should never edit this file manually**, but introduce changes only by altering `datamodel.graphql` and run `graphcool deploy`.

#### `/server/src`

- [`src/schema.graphql`](src/schema.graphql) defines your **application schema**. It contains the GraphQL API that you want to expose to your client applications.
- [`src/index.js`](src/index.js) is the entry point of your server, pulling everything together and starting the `GraphQLServer` from [`graphql-yoga`](https://github.com/graphcool/graphql-yoga).

### Common questions

#### I'm getting a 'Schema could not be fetched.' error after deploying, what gives?

Access to the Graphcool API is secured by a secret. This also applies to the introspection query. Using the latest version of GraphQL Playground, the `Authorization` header should automatically be setup with a proper JWT signing the secret. If that's not the case, you can follow these steps to access your API:

1. Visit http://jwtbuilder.jamiekurtz.com/
1. Replace the `Key` at the bottom of the page with your `secret` from the [`graphcool.yml`](./server/graphcool.yml#L5)
1. Click `Create signed JWT` and copy the obtained token
1. Now, to access the schema, use the `Authorization: Bearer <token>` header, or in the GraphQL Playground set it as JSON:
```json
{
"Authorization": "Bearer <token>"
}
```
1. Reload the schema in the Playground (the _refresh_-button is located right next to the URL of the server)

> Note: Currently, no content of the signed JWT is verified by the database! This will be implemented [according to this proposal](https://github.com/graphcool/framework/issues/1365) at a later stage.

## Contributing

Your feedback is **very helpful**, please share your opinion and thoughts! If you have any questions, join the [`#graphql-boilerplate`](https://graphcool.slack.com/messages/graphql-boilerplate) channel on our [Slack](https://graphcool.slack.com/).
5 changes: 5 additions & 0 deletions minimal/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"expo": {
"sdkVersion": "24.0.0"
}
}
30 changes: 30 additions & 0 deletions minimal/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "minimal",
"version": "0.1.0",
"private": true,
"devDependencies": {
"jest-expo": "24.0.0",
"react-native-scripts": "1.8.1",
"react-test-renderer": "16.0.0"
},
"main": "./node_modules/react-native-scripts/build/bin/crna-entry.js",
"scripts": {
"start": "react-native-scripts start",
"eject": "react-native-scripts eject",
"android": "react-native-scripts android",
"ios": "react-native-scripts ios",
"test": "node node_modules/jest/bin/jest.js --watch"
},
"jest": {
"preset": "jest-expo"
},
"dependencies": {
"apollo-client-preset": "1.0.6",
"expo": "24.0.2",
"graphql": "0.12.3",
"graphql-tag": "2.6.1",
"react": "16.0.0",
"react-apollo": "2.0.4",
"react-native": "https://github.com/expo/react-native/archive/sdk-24.0.0.tar.gz"
}
}
22 changes: 22 additions & 0 deletions minimal/server/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const { GraphQLServer } = require('graphql-yoga');

const typeDefs = `
type Query {
hello: String
}
`;

const resolvers = {
Query: {
hello() {
return 'Hello world!';
}
}
};

const server = new GraphQLServer({
typeDefs,
resolvers
});

server.start(() => console.log('Server is running on http://localhost:4000'));
Loading