Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
iceflow-server
Advanced tools
#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({
ignore: [/node_modules\/(?!iceflow)/],
redirects: {
loggedOut: 'redirect'
}
})
.addSessionMapper(function(data){
return {
user: data.user
}
})
.load()
.listen(port);
####Application Methods
app.setup() options
###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();
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.
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 => {})
You can retrieve and map headers from the response using the headers property. Headers are only mapped if they're set to a key which does not exist on the object passed into fetch (using lodash defaults).
const HttpsService = require('iceflow-server/lib/HttpService');
HttpService.fetch({
users: {
action: '/users/1',
headers: function(headers){
return {
my_prop: headers.my_prop (1)
}
}
}
}).then( data => {
console.log(data.my_prop) === 1
})
const HttpsService = require('iceflow-server/lib/HttpService');
HttpService.post({
url: '/users',
data: {
email: 'some@email.com'
}
})
.then( response => {})
###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.
###Middleware
By default two middleware files are loaded, multipart and response. Additionally the server will also look in the ./server/middleware folder for any additional middleware you would like to add.
###Conventions/Hooks
Internally the server will attempt a number of different files at startup.
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
A React/Redux Isomorphic Server
We found that iceflow-server demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
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.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.