Giter Club home page Giter Club logo

railway-routes's Introduction

Description

This is simple routing for ExpressJS framework. It allows you to write resourceful routes.

Using with Express

After creating app instead of writing code like app.get('smth', doSmth); generate routes like that:

var map = new require('railway-routes').Map(app, handler);
map.resources('posts');
map.namespace('admin', function (admin) {
   admin.resources('users');
});

In this example handler function will called immediately for each route, accepting three args: ns, controller, action and should return method which will me actually called to server request.

For example you have two controllers: posts and admin/users which looks like regular modules:

controllers/posts_controller.js

exports.show = function (req, res) {
    res.send('show');
};

exports.edit = function (req, res) {
    res.send('edit');
};

exports.destroy = function (req, res) {
    res.send('destroy');
};

...

same for controllers/admin/users_controller.js

In that case your handler should be:

function handler(ns, controller, action) {
    try {
        var ctlFile = './controllers/' + ns + controller + '_controller';
        var responseHandler =  require(ctlFile)[action];
    } catch(e) {}
    return responseHandler || function (req, res) {
        res.send('Handler not found for ' + ns + controller + '#' + action);
    };
}

Features

  • resourceful routes
  • generic routes
  • url helpers
  • namespaces
  • custom helper names / paths for resources
  • named parameters in url helpers

Docs

http://compoundjs.com/docs/#routing

Named route params

Example:

map.get('/test/:param1/:param2', 'controller#action');
map.pathTo.test({param1: 'foo', param2: 'bar'}); // '/test/foo/bar'

Singleton resources

Example:

map.resource('account');

Will generate the following routes:

GET     /account        account#show
POST    /account        account#create
GET     /account/new    account#new
GET     /account/edit   account#edit
DELETE  /account        account#destroy
PUT     /account        account#update

Singleton resources can also have nested resources. For example:

map.resource('account', function(account) {
  account.resources('posts');
});

Example app

Check out example app to deal with middleware, route handling, and generic routes:

git clone git://github.com/anatoliychakkaev/railway-routes-example-app.git
cd railway-routes-example-app
npm install
node app.js

MIT License

Copyright (C) 2013 by Anatoliy Chakkaev <mail [åt] anatoliy [døt] in>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

railway-routes's People

Contributors

1602 avatar olalonde avatar tomaash avatar fsateler avatar jfremy avatar superoul avatar tbuckley avatar

Stargazers

Patrick Luzolo avatar Akinjide Bankole avatar destinyd avatar Alberto Souza avatar TuNA avatar Xavier Spriet avatar Sharad K avatar Kaushik Thirthappa avatar 寒汀 avatar Bongsu Kang avatar Haoliang Gao avatar Aaron Kaluszka avatar Vaughan Rouesnel avatar Martin Moellenbeck avatar  avatar Tommy Chen avatar Martin Paulucci avatar Alexandre Strzelewicz avatar rguerreiro avatar Farzad Senart avatar  avatar  avatar  avatar  avatar Travis Person avatar 3000 avatar Eric Chan avatar Jonathan Brumley avatar TJ Holowaychuk avatar Dan Dean avatar Vidal Graupera avatar

Watchers

Anatoliy Chakkaev avatar  avatar Bongsu Kang avatar James Cloos avatar Patrick Luzolo avatar Vadim avatar  avatar

railway-routes's Issues

How to use midleware

Is there an example on how to use a middleware, for example if I want to load a user before executing a controller action, or if I want to add authentication to an action?

Thanks and great job!!

JB

Wildcard routes?

I'm using compoundjs to serve a RESTful api. I'm using an 'api' namespace to handle the REST calls like this:

    map.namespace('api', function (api) {
        api.get('targets',          'targets#index');
        api.get('targets/:id',      'targets#show');
        api.post('targets',         'targets#create');
        api.put('targets/:id',      'targets#update');
        api.delete('targets/:id',   'targets#destroy');
    });

On the client I am trying to use a simple backbone single-page app using pushState=true.

I'm having trouble figuring out the routing to keep node/express/compound from getting involved with anything other than the api. I've heard some mention of a wildcard route like '*' used in low-level express, maybe something like this:

app.get("*", function(req, res){
  res.sendfile('index.html');
});

When I tried doing something like map.get('', ...) and checked the route table with 'compound routes' it seemed that the '' was being treated as a string literal and it was trying to map a path like '/*', rather than recognizing it as a wildcard.

Is there some equivalent in railway-routes/compoundjs for this? Ultimately I want to preserve a request such as '/targets' or '/targets/3', server should just ignore or serve index.html and let backbone read the '/targets/3' and handle it with its client-side routing. I'm also concerned that using something like "res.sendfile('index.html')" would change the url before the client see's it, stripping the 'targets/3' before backbone can respond to it.

I found some similar Q&A on Stack Overflow but nothing that seemed to be specific to compoundjs or railway-routes.

Any suggestions, or documentation links would be greatly appreciated. Thanks!

Undocumented `state` option in `#getParams`

What is this for?

        if ('state' in params) {
            p.state = params.state;
        }

I am using it to pass options through to my resource handler - but I want to know if it will change in the future and what it is used for.

How to add a filter in routes like you do in express ?

In express, I can add a certain filter just to check if a User has been logged in or not by doing something like this :-

app.get('/posts', ensureLoggedIn(), posts.index);

How do i induce the ensureLoggedIn() behaviour using railway-routes ?

api broken

after your commits to close #16
a few bugs are introdused to break the app again :)

nested routes in compund:

map.resources 'users', (usesr)->
    uses.resources 'posts', (posts)->
                posts.post 'rate.:format?', 'posts#rate'

it used to be

user = {id : 4}
post = {id: 2}
pathTo.user_post( user, post) to create /users/4/posts/2 
pathTo.user_post( 4, 2) to create /users/4/posts/2 
pathTo.user_post_rate( 4, 2) to create /users/4/posts/2/rate 

now it is:

pathTo.user_post( user, post) creates /users/4/posts/4 
pathTo.user_post( 4, 2) creates /users/4/posts/2 
pathTo.user_post_rate( 4, 2) creates /users/4/posts/2/rate
pathTo.user_post_rate( user, post) creates /users/4/posts/2/rate
pathTo.user_post_rate( {user_id: user.id, id : post.id}) creates /users/4/posts/undefined/rate

but i guess you wanted:

pathTo.user_post( {user_id: user.id, id : post.id}) to create /users/4/posts/4 

the problem is that API is not same now
and OLD code is broken .....
i think both methods should work
i like the idea to pass the object to pathTo method, but alse some times it is much better to pass each param separatly

Issue with invalid controller actions

Hey @1602 I noticed an issue wen routing invalid actions

If I do http://localhost:300/accounts the action of the accounts controller defaults to index, if I do http://localhost:300/accounts/index this also default to index but if I do http://localhost/accounts/invalid-action I get defaulted to the show action(which I think is weird) instead of getting the "Handler not found" error message, is this intentional or it is a bug?.

Any ideas?

Thank you!

JB

This is my test handler.

module.exports = function (app) {
    var map = new routing.Map(app, handler);    
    map.resources('accounts');  
};

function handler(ns, controller, action) {
    try {
        var ctlFile = './controllers/' + ns + controller + '_controller';
        var responseHandler =  {
            index: function (req, res) {
                res.send('IN INDEX');
            },

            show: function (req, res) {
                res.send('IN SHOW');
            },

            new: function (req, res) {
                res.send('IN NEW');
            },

            edit: function (req, res) {
                res.sed('IN EDIT');
            }

        }[action];
    } catch(e) {}
    return responseHandler || function (req, res) {
        res.send('Handler not found for ' + ns + controller + '#' + action);
    };
}

as option does not work as expected

At least, not as I expected ;). The railway-routes test has the following:

map.resources('avatars', {as: 'images', path: 'pictures'});
test.equal(map.pathTo.pictures, '/pictures');

On my expectations that should fail. Since as: is being specified, pathTo.pictures should not exist, but instead we should have pathTo.images.

Would you accept patches to change this behavior?

Order in `only` param matters

If I call resources with {only: ['index', 'show', 'new', 'create']}, /resource/new is interpreted as a show request for id new.

Access resource name in handler when using custom controller names.

If I do something like this:

api.resources 'collections', (collection) ->
      collection.resources 'links', controller: 'collectionLinks'

I wish to access the name of the resource (that is, "links"/"link") from the collectionLinks resource.

The callback receives the controllerName and there is no way to access the name of the resource.

path_to for routes with optional parameters doesn't work

By defining

map.get('/test/:p1?', 'home#test');

When I use path_to

map.pathTo.test()
// I get ''
map.pathTo.test('param1')
// I get '/test/param1?'

A cool feature would be to declare route parameters like that :

map.get('/test/:p1/:p2?', 'home#test');

And to map them like that :

map.pathTo.test({p1 : 'param1', p2 : 'param2'})

Anyway thanks for this very nice piece of code

History.md

Hi, can you add a History.md so it can be clearly seen what was changed between each release?

Rename the package?

Hey! I just realized this npm module is completely decoupled from RailwayJS which I think it's great. Do you plan to develop it completely independently from RailwayJS? If so, why not rename the project or make it clear in the README.md. Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.