@beardedtim/cms-server

0.0.3 • Public • Published

@beardedtim/cms-server

WIP

Build Status

codecov

Overview

This is very much a WIP. It currently is aiming to do two things:

  1. Simplify the startup of a Koa project
  2. Encourage building instead of setting up

I am hoping eventually to have this as a working Blogging/page-building platform. As of now, it is easy to add basic endpoints such as /resource and /resource/:id with little configuration.

Currently, the server only supports Node v7.9.0. Checkout nvm for managing node versions

Configuration API

{
    collections: [
      {
        resource: 'collectionName',
        pre: [ ... ], // async functions to run BEFORE route
        post: [ ... ], // async functions to run AFTER route
        protected: true, // if this is a protected route
        authFn: validateFunc // custom async validation
        route: KoaRoute // a KoaRouter compatable obj | defaults to Base(config) | no route pre/post added
      }
    ],
    pre: [ ... ], // async functions to run BEFORE ALL routes
    post: [ ... ], // async functions to run AFTER ALL routes,
}

Developing

$ git clone https://github.com/beardedtim/cms-server.git

$ cd cms-server

$ cp .env.example .env

$ yarn

$ yarn dev

You will need a mongodb instance running and have the correct MONGO_URI set in your .env file.

Working Examples:

Below you will find 4 examples of how to use the API. To run examples:

$ git clone https://github.com/beardedtim/cms-server.git

$ cd cms-server

$ yarn

$ cd examples

$ cd defaults

$ cp .env.example .env

$ node server.js

Data Flow

Each request to a valid endpoint will flow:

  1. Set expected values for
  2. All config.pre functions are applied in order
  3. All collections are added as routes in order
  4. All config.post functions are applied in order

Tutorial:

Working Example v.0.0.1

Inside of our root directory:

$ yarn add @beardedtim/cms

$ touch index.js

$ touch .env

Add the following to .env:

PORT=5001
MONGO_URI=mongodb://localhost:32770/explore
AUTH_NAME=timi
AUTH_PASS=1234

Fill in the correct MONGO_URI that you are using. If you are not already, checkout Docker and Kitematic for an almost point and click setup experience.

Then inside of index.js:

const dotenv = require('dotenv');
const Koa = require('koa');

dotenv.config();

const app = new Koa();
const cmsServer = require('./').server;

cmsServer.booststrap(app);

app.listen(5000);

We now have a functional applicaton at http://localhost:5001 with an endpoint at /documents and /documents/:id. It also has protected routes for PUT,PATCH,DELTE methods.

Go ahead and try a GET requests to http://localhost:5001/documents. It should return the following:

{
    data: []
}

Which means we have no documents. Let's fix that. Add the following to your request header and make a POST request:

Authorization: Basic dGltaToxMjM0
Content-Type: application/json
Body: {
    name: 'Tim'
}

This can be done inside of postman by clicking Authorization, choosing Basic and typing timi for the name and 1234 for the password. It can also be added via fetch:

fetch('http://localhost:5001/documents', {
    method: 'POST',
    headers: {
        'Authorization': 'Basic dGltaToxMjM0',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        name: 'Tim'
    })
})

NOTE: If you get TypeError: Cannot create property '_id' on string, it is probably because you did not set Content-Type to application/json

You should get back the following:

{
  "data": {
    "insertedIds": [
      "58fd730a37b1e45c818003b2"
    ]
  }
}

If you get:

{
  "error": {
    "code": 406,
    "message": "Unacceptable content-type! It must be applcation/json"
  }
}

This is because you did not set the Content-Type header correctly.

Now let's go back to GET /documents and see what we get:

{
    data: [
        // ... whatever you pushed
    ]
}

And we should have an _id. Go ahead and copy that and go to:

http://localhost:5001/documents/<ID HERE>

It should return:

{
  "data": {
    "_id": "58fd26666464e505d044556d",
    "name": "Tim"
  }
}

Or whatever you set that record to.

This is a boring record so let's delete it:

DELETE /documents/:id

DELETE /documents/58fd26666464e505d044556d

should return something like:

{
  "data": {
    "n": 1,
    "ok": 1
  }
}

And if we want to delete the whole collection of documents and start again?

DELETE /documents

should return:

{
  "data": true
}

And when we GET /documents, we should be met with:

{
    data: []
}

Adding Custom Functionality

Adding Custom 404

boostrapConfig = {
    // ...
    post: [
        async (ctx, next) => {
            if (!ctx.body) {
                ctx.body = {
                    error: {
                        droids: 'not the ones you are looking for',
                    }
                }
            }
        }
    ],
}

request: GET /not/real/route

response:

{
  error: {
    droids: 'not the ones you are looking for'
  }
}

Adding Custom Query Validation

boostrapConfig = {
    // ...
    pre: [
        async (ctx, next) => {
            const { query } = ctx.request;
            const isValid = customValidation(query);
            if (!isValid) {
                ctx.errors.custom({
                    code: 406,
                    message: 'Not valid query!',
                });
            }
        }
    ]
}

request: GET /documents?invalid=true

response:

{
  error: {
    code: 406,
    message: 'Not valid query!',
  }
}

Versions

Current Tags

  • Version
    Downloads (Last 7 Days)
    • Tag
  • 0.0.3
    3
    • latest

Version History

  • Version
    Downloads (Last 7 Days)
    • Published
  • 0.0.3
    3
  • 0.0.2
    0
  • 0.0.1
    1

Package Sidebar

Install

npm i @beardedtim/cms-server

Weekly Downloads

4

Version

0.0.3

License

UNLICENSE

Last publish

Collaborators

  • beardedtim