Skazka

Skazka

  • Server
  • Examples
  • Github
  • Blog

›Server

Server

  • REST API
  • GraphQL
  • Serverless
  • SPA

Server Serverless

This example shows how to create GraphQL and REST APIs using Serverless.

How to install

npm i @skazka/server @skazka/server-body-parser @skazka/server-cors @skazka/server-graphql @skazka/server-http @skazka/server-init @skazka/server-router aws-serverless-express serverless serverless-offline debug graphql axios jest

With yarn:

yarn add @skazka/server @skazka/server-body-parser @skazka/server-cors @skazka/server-graphql @skazka/server-http @skazka/server-init @skazka/server-router aws-serverless-express serverless serverless-offline debug graphql axios jest

How to use

db/index.js

It's emulation of any database.

const users = [];

module.exports = users;

graphql/index.js

const {
  GraphQLSchema,
  GraphQLObjectType,
  GraphQLString,
  GraphQLList,
} = require('graphql');

const users = require('../db');

const UserType = new GraphQLObjectType({
  name: 'UserType',
  description: 'User type',
  fields: {
    name: {
      type: GraphQLString,
    },
  },
});

const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: 'QueryType',
    fields: {
      users: {
        type: new GraphQLList(UserType),
        resolve() {
          return users;
        },
      },
    },
  }),
  mutation: new GraphQLObjectType({
    name: 'MutationType',
    fields: {
      users: {
        type: new GraphQLList(UserType),
        args: {
          name: {
            type: GraphQLString,
          },
        },
        resolve(parent, { name }) {
          users.push({ name });

          return users;
        },
      },
    },
  }),
});

const graphiql = true;

module.exports = { schema, graphiql };

router/index.js

const Router = require('@skazka/server-router');

const graphql = require('@skazka/server-graphql');
const bodyParser = require('@skazka/server-body-parser');

const { schema, graphiql } = require('../graphql');
const users = require('../db');

const router = new Router();

router.all('/').then(graphql({ schema, graphiql }));

router.get('/users').then(ctx => ctx.response(users));

router.post('/users').then(async (ctx) => {
  await bodyParser.json(ctx);

  users.push(ctx.request.body);

  return ctx.response({ message: 'User saved' });
});

module.exports = router;

app/index.js

const Server = require('@skazka/server');

const init = require('@skazka/server-init');
const cors = require('@skazka/server-cors');

const router = require('../router');

const server = new Server();

server
  .then(init({ error: { isJSON: true } }))
  .then(cors())
  .then(router.resolve());

module.exports = server;

index.test.js

const srv = require('@skazka/server-http');
const axios = require('axios');
const httpAdapter = require('axios/lib/adapters/http');

const app = require('./app');

const host = `http://localhost:${process.env.PORT || '3000'}`;

axios.defaults.host = host;
axios.defaults.adapter = httpAdapter;

describe('GraphQL example test', async () => {
  let server;

  beforeEach(() => {
    server = srv.createHttpServer(app);
  });

  afterEach((done) => {
    server.close(done);
  });

  test('It should test GET graphql request', async () => {
    await axios.get(`${host}/?query={ users { name } }`).then((response) => {
      expect(response.status).toEqual(200);
      expect(response.statusText).toEqual('OK');
      expect(response.data.data.users).toEqual([]);
      // helmet headers
      expect(response.headers['x-dns-prefetch-control']).toEqual('off');
      expect(response.headers['x-frame-options']).toEqual('SAMEORIGIN');
      expect(response.headers['strict-transport-security']).toEqual('max-age=15552000; includeSubDomains');
      expect(response.headers['x-download-options']).toEqual('noopen');
      expect(response.headers['x-content-type-options']).toEqual('nosniff');
      expect(response.headers['x-xss-protection']).toEqual('1; mode=block');
      // cors header
      expect(response.headers['access-control-allow-origin']).toEqual('*');
      // init({ error: { isJSON: true } }) it sets json header
      expect(response.headers['content-type']).toEqual('application/json; charset=utf-8');
    });
  });

  test('It should test POST graphql request', async () => {
    await axios.post(`${host}/`, { query: '{ users { name } }' }).then((response) => {
      expect(response.status).toEqual(200);
      expect(response.statusText).toEqual('OK');
      expect(response.data.data.users).toEqual([]);
      // helmet headers
      expect(response.headers['x-dns-prefetch-control']).toEqual('off');
      expect(response.headers['x-frame-options']).toEqual('SAMEORIGIN');
      expect(response.headers['strict-transport-security']).toEqual('max-age=15552000; includeSubDomains');
      expect(response.headers['x-download-options']).toEqual('noopen');
      expect(response.headers['x-content-type-options']).toEqual('nosniff');
      expect(response.headers['x-xss-protection']).toEqual('1; mode=block');
      // cors header
      expect(response.headers['access-control-allow-origin']).toEqual('*');
      // init({ error: { isJSON: true } }) it sets json header
      expect(response.headers['content-type']).toEqual('application/json; charset=utf-8');
    });
  });

  test('It should test GET /users', async () => {
    await axios.get(`${host}/users`).then((response) => {
      expect(response.status).toEqual(200);
      expect(response.statusText).toEqual('OK');
      expect(response.data).toEqual([]);
      // helmet headers
      expect(response.headers['x-dns-prefetch-control']).toEqual('off');
      expect(response.headers['x-frame-options']).toEqual('SAMEORIGIN');
      expect(response.headers['strict-transport-security']).toEqual('max-age=15552000; includeSubDomains');
      expect(response.headers['x-download-options']).toEqual('noopen');
      expect(response.headers['x-content-type-options']).toEqual('nosniff');
      expect(response.headers['x-xss-protection']).toEqual('1; mode=block');
      // cors header
      expect(response.headers['access-control-allow-origin']).toEqual('*');
      // init({ error: { isJSON: true } }) it sets json header
      expect(response.headers['content-type']).toEqual('application/json');
    });
  });

  test('It should test POST /users', async () => {
    await axios.post(`${host}/users`, { name: 'test' }).then((response) => {
      expect(response.status).toEqual(200);
      expect(response.statusText).toEqual('OK');
      expect(response.data.message).toEqual('User saved');
      // helmet headers
      expect(response.headers['x-dns-prefetch-control']).toEqual('off');
      expect(response.headers['x-frame-options']).toEqual('SAMEORIGIN');
      expect(response.headers['strict-transport-security']).toEqual('max-age=15552000; includeSubDomains');
      expect(response.headers['x-download-options']).toEqual('noopen');
      expect(response.headers['x-content-type-options']).toEqual('nosniff');
      expect(response.headers['x-xss-protection']).toEqual('1; mode=block');
      // cors header
      expect(response.headers['access-control-allow-origin']).toEqual('*');
      // init({ error: { isJSON: true } }) it sets json header
      expect(response.headers['content-type']).toEqual('application/json');
    });

    await axios.get(`${host}/users`).then((response) => {
      expect(response.status).toEqual(200);
      expect(response.statusText).toEqual('OK');
      expect(response.data[0].name).toEqual('test');
      // helmet headers
      expect(response.headers['x-dns-prefetch-control']).toEqual('off');
      expect(response.headers['x-frame-options']).toEqual('SAMEORIGIN');
      expect(response.headers['strict-transport-security']).toEqual('max-age=15552000; includeSubDomains');
      expect(response.headers['x-download-options']).toEqual('noopen');
      expect(response.headers['x-content-type-options']).toEqual('nosniff');
      expect(response.headers['x-xss-protection']).toEqual('1; mode=block');
      // cors header
      expect(response.headers['access-control-allow-origin']).toEqual('*');
      // init({ error: { isJSON: true } }) it sets json header
      expect(response.headers['content-type']).toEqual('application/json');
    });

    await axios.post(`${host}/`, { query: '{ users { name } }' }).then((response) => {
      expect(response.status).toEqual(200);
      expect(response.statusText).toEqual('OK');
      expect(response.data.data.users[0].name).toEqual('test');
      // helmet headers
      expect(response.headers['x-dns-prefetch-control']).toEqual('off');
      expect(response.headers['x-frame-options']).toEqual('SAMEORIGIN');
      expect(response.headers['strict-transport-security']).toEqual('max-age=15552000; includeSubDomains');
      expect(response.headers['x-download-options']).toEqual('noopen');
      expect(response.headers['x-content-type-options']).toEqual('nosniff');
      expect(response.headers['x-xss-protection']).toEqual('1; mode=block');
      // cors header
      expect(response.headers['access-control-allow-origin']).toEqual('*');
      // init({ error: { isJSON: true } }) it sets json header
      expect(response.headers['content-type']).toEqual('application/json; charset=utf-8');
    });
  });

  test('It should test POST graphql request to add data', async () => {
    await axios.post(`${host}/`, {
      query: `
      mutation getUsers {
        users(name: "test") {
          name
        }
       }
       `,
    }).then((response) => {
      expect(response.status).toEqual(200);
      expect(response.statusText).toEqual('OK');
      expect(response.data.data.users[0].name).toEqual('test');
      // helmet headers
      expect(response.headers['x-dns-prefetch-control']).toEqual('off');
      expect(response.headers['x-frame-options']).toEqual('SAMEORIGIN');
      expect(response.headers['strict-transport-security']).toEqual('max-age=15552000; includeSubDomains');
      expect(response.headers['x-download-options']).toEqual('noopen');
      expect(response.headers['x-content-type-options']).toEqual('nosniff');
      expect(response.headers['x-xss-protection']).toEqual('1; mode=block');
      // cors header
      expect(response.headers['access-control-allow-origin']).toEqual('*');
      // init({ error: { isJSON: true } }) it sets json header
      expect(response.headers['content-type']).toEqual('application/json; charset=utf-8');
    });

    await axios.post(`${host}/`, { query: '{ users { name } }' }).then((response) => {
      expect(response.status).toEqual(200);
      expect(response.statusText).toEqual('OK');
      expect(response.data.data.users[0].name).toEqual('test');
      // helmet headers
      expect(response.headers['x-dns-prefetch-control']).toEqual('off');
      expect(response.headers['x-frame-options']).toEqual('SAMEORIGIN');
      expect(response.headers['strict-transport-security']).toEqual('max-age=15552000; includeSubDomains');
      expect(response.headers['x-download-options']).toEqual('noopen');
      expect(response.headers['x-content-type-options']).toEqual('nosniff');
      expect(response.headers['x-xss-protection']).toEqual('1; mode=block');
      // cors header
      expect(response.headers['access-control-allow-origin']).toEqual('*');
      // init({ error: { isJSON: true } }) it sets json header
      expect(response.headers['content-type']).toEqual('application/json; charset=utf-8');
    });

    await axios.get(`${host}/users`).then((response) => {
      expect(response.status).toEqual(200);
      expect(response.statusText).toEqual('OK');
      expect(response.data[0].name).toEqual('test');
      // helmet headers
      expect(response.headers['x-dns-prefetch-control']).toEqual('off');
      expect(response.headers['x-frame-options']).toEqual('SAMEORIGIN');
      expect(response.headers['strict-transport-security']).toEqual('max-age=15552000; includeSubDomains');
      expect(response.headers['x-download-options']).toEqual('noopen');
      expect(response.headers['x-content-type-options']).toEqual('nosniff');
      expect(response.headers['x-xss-protection']).toEqual('1; mode=block');
      // cors header
      expect(response.headers['access-control-allow-origin']).toEqual('*');
      // init({ error: { isJSON: true } }) it sets json header
      expect(response.headers['content-type']).toEqual('application/json');
    });
  });
});

package.json

{
  "name": "example-serverless",
  "version": "0.0.0",
  "description": "",
  "private": true,
  "main": "index.js",
  "scripts": {
    "start": "node bin/www",
    "test": "PORT=7000 jest  --coverage --runInBand",
    "serverless": "sls offline start",
    "deploy": "sls deploy",
    "remove": "sls remove"
  },
  "keywords": [
    "graphql",
    "node.js",
    "skazka",
    "cors",
    "serverless"
  ],
  "author": "skazkajs",
  "license": "MIT",
  "dependencies": {
    "@skazka/server": ">=0.0.0",
    "@skazka/server-body-parser": ">=0.0.0",
    "@skazka/server-cors": ">=0.0.0",
    "@skazka/server-graphql": ">=0.0.0",
    "@skazka/server-http": ">=0.0.0",
    "@skazka/server-init": ">=0.0.0",
    "@skazka/server-router": ">=0.0.0",
    "aws-serverless-express": ">=3.3.5",
    "axios": ">=0.18.0",
    "debug": ">=4.0.0",
    "graphql": ">=14.0.0",
    "jest": ">=23.6.0",
    "serverless": ">=1.36.1",
    "serverless-offline": ">=3.33.0"
  }
}

bin/www

#!/usr/bin/env node

const server = require('@skazka/server-http');
const app = require('../app');

server.createHttpServer(app);

index.js

const awsServerlessExpress = require('aws-serverless-express');

const app = require('./app');

module.exports.handler = (event, context) => awsServerlessExpress.proxy(
  awsServerlessExpress.createServer(app.resolve()),
  event,
  context,
);

serverless.yml

service: serverless-example

plugins:
  - serverless-offline

provider:
  name: aws
  runtime: nodejs8.10
  stage: dev
  region: eu-central-1

functions:
  app:
    handler: index.handler
    events:
      - http: ANY /
      - http: 'ANY {proxy+}'

Commands

Run app

npm start

Or

yarn start

Test app

npm test

Or

yarn test

Run app using serverless

npm run serverless

Or

yarn serverless

Run app using AWS lambda

npm run deploy

Or

yarn deploy

Clear AWS lambda

npm run remove

Or

yarn remove    

More docs

  • Server
  • Server init
  • Server GraphQL
  • Server Router
  • Server Body Parser
  • Server CORS
  • Server HTTPS(S)
  • GraphQL.js
  • Serverless
  • Serverless offline
  • AWS Serverless Express
  • AWS - Credentials

Copy from git

Clone:

git clone https://github.com/skazkajs/skazka.git
cd skazka/examples/serverless

Install:

npm i

Or

yarn

And run start, test, serverless, deploy or remove commands.

Last updated by Evheniy Bystrov
← GraphQLSPA →
  • How to install
  • How to use
    • db/index.js
    • graphql/index.js
    • router/index.js
    • app/index.js
    • index.test.js
    • package.json
    • bin/www
    • index.js
    • serverless.yml
  • Commands
    • Run app
    • Test app
    • Run app using serverless
    • Run app using AWS lambda
    • Clear AWS lambda
  • More docs
  • Copy from git
Copyright © 2019 SkazkaJS