/nap

[WIP] NextJS + Apollo + PassportJS

Primary LanguageJavaScriptMIT LicenseMIT

Commitizen friendly

nap

[WIP] NextJS/ApolloJS/PassportJS Build in Next JS for SSR, Apollo Client for GraphQL, Passport JS for authentication, Docker for development and production.

Overview

○ Docker
├─ ○ Docker Compose 3.1
│  ├─ Docker Swarm Stack
│  └─ Docker Flow Proxy
│
├─ ○ Nginx
│  ├─ ./nginx/certs   : /etc/nginx/certs
│  ├─ ./nginx/conf.d  : /etc/nginx/conf.d
│  ├─ ./nginx/log     : /var/log/nginx
│  └─ ./nginx/www     : /var/www
│
├─ ○ NodeJS 7.6, nodemon
│  ├─ ○ NextJS 2
│  │  ├─ ./pages      : /usr/app/pages
│  │  ├─ ./components : /usr/app/components
│  │  ├─ ./lib        : /usr/app/lib
│  │  ├─ ./routes     : /usr/app/routes
│  │  └─ ./server     : /usr/app/server
│  │
│  ├─ ○ Apollo GraphQL
│  │  └─ ./graphql    : /usr/app/graphql
│  │
│  └─ ○ PassportJS, Redis
│     └─ ./providers  : /usr/app/providers
│
├─ ○ Redis : redis://redis
│  └─ data            : /data
│
└─ ○ MongoDB : mongodb://mongo/graphql
   └─ data            : /data/db

Stacks

Extras


Configurations

Copy from .env.example template and .env as you wish

cp .env.example .env

Develop

# To build and run docker compose (it take sometime for first build)
npm run up

# Try modify files and see the HMR result
open http://localhost:3000

# Try modify file in ./graphql and see the result via GraphiQL
open http://localhost:3000/graphql

Debug

  • Server side : Use VSCode and press F5 to attach with nodejs
  • Client side : Use Chrome Dev Tool

Addition

# To kill all and tear down
npm run down

# To dive in container
npm run in

Test

# Will need to run server for integration test (WIP)
npm run up

# To test all with Jest
npm run test

# To see coverage
npm run cover

GraphQL extend default fields

// Just modify ./graphql/custom.js
// To add `score` field as `Number` to `User` collection
exports.extraUserSchema = {
  score: Number
}

// To add `FCMToken` field as `String` to `Installation` collection
exports.extraInstallationSchema = {
  FCMToken: String
}

// To add `isVerified` field as `Boolean` to `Installation` collection
exports.extraInstallationSchema = {
  isVerified: Boolean
}

GraphQL examples

# For original graphql-compose examples
cp -r ./examples/schema-graphql-compose/ ./graphql/
open http://localhost:3000/graphql/user

# For Apollo style with graphql-tools
cp -r ./examples/schema-graphql-tools/ ./graphql/
open http://localhost:3000/graphql/apollo

# For original style
cp -r ./examples/schema-original/ ./graphql/
open http://localhost:3000/graphql/original

Passport (cookie)

Will need test after refactoring

Passport (token via GraphQL)

  • Facebook

    Use with Ract Native after get access_token form Facebook, See nap-react-native

    # Login with Facebook access_token and device's info
    mutation loginWithFacebook($deviceInfo: String!, $accessToken: String!) {
      loginWithFacebook(deviceInfo: $deviceInfo, accessToken: $accessToken) {
        sessionToken
        user {
          _id
          name
        }
      }
      errors {
        code
        message
      }
    }
    
    # To get user profile
    {
      user {
        name
      }
      errors {
        code
        message
      }
    }
    
    # Logout with current bearer session token
    mutation {
      logout {
        isLoggedIn
      }
    }
  • Log in with email

    Will to setup MailGun bofore use.

    MAILGUN_API_KEY=key-SOME_RANDOM_NUMBER_HERE
    MAILGUN_DOMAIN=foo.bar

    And optional modify email template at ./template/email-register.js Then log in with GraphQL
    Status should return as WAIT_FOR_EMAIL_VERIFICATION and VERIFIED_BY_EMAIL after visit verified link.

    mutation loginWithEmail($deviceInfo: String!, $email: String!) {
      loginWithEmail(deviceInfo: $deviceInfo, email: $email) {
        sessionToken
        user {
          _id
          status
        }
      }
      errors {
        code
        message
      }
    }
    

Client example

DOING

  • Link facebook-token with auth/facebook user.
  • Link facebook-token with auth/email user.
  • Unlink Facebook via React web.
  • Handle cookies via React Native

TODO

TOTEST

  • Redis fail test.
  • MongoDB fail test.
  • HTTP fail test.
  • HTTPS fail test.
  • Unit test graphql-compose.
  • Basic signin test.
  • Passport test.
  • Sessions expire test.
  • Chaos testing with pumba

TOCUSTOM

  • Custom MongoDB replication docker exec -it node1 mongo --eval "rs.initiate()"
  • Run Multiple Docker Environments (qa, stage, prod) from the Same docker-compose File.
  • HTTPS with https://github.com/expressjs/session#cookiesecure
  • Production vs Development. docker-compose -f docker-compose.yml -f production.yml up -d
  • Container config e.g. restart policy, limits CPU/RAM.
    version: "3"
    services:
      web:
        image: web
        labels:
          com.example.description: "This label will appear on all containers for the web service"
        deploy:
          labels:
            com.example.description: "This label will appear on the web service"
          resources:
            limits:
              cpus: '0.001'
              memory: 50M
            reservations:
              cpus: '0.0001'
              memory: 20M
          mode: replicated
          replicas: 6
          update_config:
            parallelism: 2
            delay: 10s
          restart_policy:
            condition: on-failure
          placement:
            constraints:
              - node.role == manager
              - engine.labels.operatingsystem == ubuntu 14.04
    

TOHAVE