Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

iceflow-server

Package Overview
Dependencies
Maintainers
1
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

iceflow-server

A React/Redux Isomorphic Server

  • 0.2.0
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
1
decreased by-66.67%
Maintainers
1
Weekly downloads
 
Created
Source

#Iceflow Server

Iceflow-server is a react isomorphic server concept written to explore a different way of building an isomorphic server. It's intended to be both turn-key and opinionated. It is built on Express and uses React with Redux/React-Redux.

##Quick Start

For an example server setup git clone https://github.com/mikehoren/iceflow-server-example

##Installation

npm install iceflow-server --save

##Server Structure

/app
-- /components
-- Application.js
-- /controllers
-- /reducers
-- routes.js
/config
/logs
/public
-- /sass
-- /build
-- /fonts
-- /images
/server
-- /api
-- /actions
-- /routes
-- /lib
-- /migrations
-- /models
-- bootstrap.js
/tests
/utils
/views
app.js

##Building the App

###Setup

Sample app.js


'use strict';

const express      = require('express');
const path         = require('path');
const favicon      = require('serve-favicon');
const logger       = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser   = require('body-parser');
const port         = 3000;
const sessions     = require('client-sessions');
const colors       = require('colors');
const app          = require('iceflow-server');

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use(sessions({
    cookieName: 'session',
    secret: 'iceflow',
    duration: 24 * 60 * 60 * 1000,
    activeDuration: 1000 * 60 * 5
}));

app
  .setup()
  .addSessionMapper(function(data){
    return {
      user: data.user
    }
  })
  .load()
  .listen(port);

####Application Methods

  • app.setup() - Autoloads the built in middleware and the api routes.
  • app.addSessionMapper(fn) - this method takes a function which is used as a mapping function to determine what session data to pass to the client.
  • app.load() - this method loads your React application on the server.
  • app.listen(port) - Start the server and listen on the designated port.

###Components

Create an Application.js component in app/components as your root react component. Require react-redux when you want to connect with the store. From within your main Application component the page to view will be available as the prop Page.

###Routes

The routes files contain your navigatable application routes.


'use strict';

const routes = {

  '/': {
    //the controller to use
    controller        : 'Index',
    //the action to call on the controller
    action            : 'index',
    //the component to use as your base component for the page
    component         : 'index/Page',
    //redirectIfLoggedIn/redirectIfLoggedOut if your user has a session the router will redirect the user to the url you designate
    redirectIfLoggedIn: '/dashboard'
  }

}

module.exports = routes;

###Controllers

Controllers run when the user navigates to a url specified in your routes. If the url has no match in routes Iceflow-server will assume you want the NotFound controller with an index action and will attempt to load components/not_found/Page. Controllers run on the client and server and it's expected they will only make GET requests.

Example controller

'use strict';

const Controller = require('iceflow-server/lib/Controller');

class Index extends Controller {

    constructor(){
        super();
    }

    index(req, res){
    this.render(req, res, {
      title     : 'Iceflow Server'
    }); 
    }

}

module.exports = new Index();

  • render(req, res, data) - the render method will trigger the app to render the associated action for the route. The data property will be passed to the final markup on the server. On the client it will be saved to the store using lodash.assign.
this.render(req, res, {
    title     : 'Iceflow Server Dashboard',
    data      : {
        key: 'value'
    }
});

###HttpService

The HttpService module is used to make CRUD requests or parallel GET requests.

  • fetch(spec) - fetch will make parallel requests based on the passed in spec. The spec should take the form {key: {url: '/', data: {}, api: 'someApiKey'}} and return {key: {key: 'value'}}. This method returns a promise.

The api key is intended to be a string which matches up with an api endpoint in your application.js config file. This endpoint will server as the host for your request. The url will be appended on the end. The url property is always intended as relative, either to the server or to the api.

HttpService.fetch is the ideal way to make requests at the controller level.

An example fetch request

const HttpsService = require('iceflow-server/lib/HttpService');

HttpService.fetch({
  users: {
    action: '/users',
    api   : 'test'
  }
}).then( data => {})

The api key is matched to config/Application.js

module.exports = {

  apis: {
    test: 'https://someexternalapi.com'
  }

};

On the server for non-remote routes fetch will attempt to run the actual actions by convention.

{
  action: '/users'
}

would get api/actions/users/get.js

{
  action: '/users/example'
}

would get api/actions/users/get_example.js

{
  action: '/users/1'
}

would get api/actions/users/get_show.js.  Numeric values for a specific resource get converted to getShow.

For params and query data the fetch method has a data key. Example:

const HttpsService = require('iceflow-server/lib/HttpService');

HttpService.fetch({
  users: {
    action: '/users/1',
    data: {
      params: {
        id: 1
      },
      query: {
        x: 2
      }
    }
  }
}).then( data => {})

  • get/post/put/patch/delete (object) - Crud methods take an object in the form {url: '/', data: {}, cors: false} and returns a promise.
const HttpsService = require('iceflow-server/lib/HttpService');

HttpService.post({
    url: '/users',
    data: {
        email: 'some@email.com'
    }
})
.then( response => {})

  • render(req, res, data) - An alias for Renderer.render, call when you're ready to render the page.

###Events

The Events module is the central event aggregator for your app. It's just an alias for node/events. The "on" method of Events is a wrapper for the native method, this method by default will not add events on the server to prevent memory leaks. If you need to add events on the server set a third argument as true for "on". There are a few built in events used for routing. These events are intended for the client only.

route - This will trigger the router to route to the passed in url

const Events = require('iceflow-server/lib/Events');

Events.emit('route', '/newurl');

route:start - this will trigger as soon as the router begins to route to a new url.

const Events = require('iceflow-server/lib/Events');

Events.on('route:start', doSomething);

route:set - This will trigger after the url changes but before the controller action is run.

route:complete - This will trigger after the controller action but before the application is rerendered.

route:mounted - This will trigger when routing is complete.

###Reducers

Reducers for your redux store should be located in app/reducers. The server will look at reducers.js and use the exported object to create the single reducer. An example app/reducers/reducers.js file might look like


const reducer1 = require('./reducer1');
const reducer2 = require('./reducer2');

module.exports = {
  reducer1,
  reducer2
};

###Request and Response Objects

For the most part you can use these normally both on the backend and frontend in the context of /app. There are some built in helpful additions/modifications to the request object from within your controller files.

req.fetch() - An alias for HttpService.fetch().

req.store - Each request has a seperate store on the server, on the client it points to the same single store.

req.route - Contains the route configuration for the requested route from your route config.

###Conventions/Hooks

Internally the server will attempt a number of different files at startup.

  • app/routes.js - These contain the routes that are navigatable in your app.
  • config/application.js - These contain application configurations used on both the backend and FRONTEND. In this object it uses the apis key when calling fetch() in HttpService. The pushstate key is used to determine if the app should use pushstate or server-render every page.
  • views/index.ejs - The page layout that is server-rendered.
  • server/bootstrap.js - This is a hook to do server things and is run before the router is initialize (navigatable routes are loaded) but after server api routes and internal middleware is loaded.
  • app/reducers/reducers.js - Redux reducers are pulled in and applied to the app's store at startup. It's expected functions will be exported in each file with the signature (state, action).
  • server/api - Server routes are autoloaded when app.setup() is called. A server route consists of two parts. The routing part is in server/api/routes. The action is in server/api/actions. By convention actions should start with the method of the request.

in server/api/routes/users.js


'use strict';

const getAction         = require('../actions/users/get');
const postExampleAction = require('../actions/users/postExample');

module.exports = app => {
  app.get('/api/users', getAction);
  app.post('/api/users/example', postExampleAction);
}

In terms of how you structure the other server-related pieces of your app including databases and migrations that's complete up to you and you have plenty of flexibility on how to approach these parts.

FAQs

Package last updated on 25 Feb 2016

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc