GithubHelp home page GithubHelp logo

express-resource's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

express-resource's Issues

Singular resources

we could use lingo.en.isSingular() to detect and auto-magically support this

Question: A way to nest resources?

How can I nest resources in order to have URL schemas like:

/post/{post_id}/comments
/post/{post_id}/comments/{comment_id}

/post/1/comments
/post/1/comments/54

Add accepted type negotiation

Currently express-resource uses the :format parameters for matching requested resource format (.xml, .json, etc).

In addition to this, it would be nice to support the HTTP Accept headers. connect-conneg provides a parser for them that organizes the requested formats by preference.

This can already be used with express-resource, but requires some boilerplate. First you need to add the conneg middleware:

server.use require('connect-conneg').acceptedTypes

And then handle the types in the default content negotiation handler:

default: (req, res, next) ->
  for type in req.acceptableTypes
    if this.html and type is 'text/html'
      return this.html req, res, next
    if this.json and type is 'application/json'
      return this.json req, res, next
  next()

It would be very useful if the default implementation of default did this, instead of falling back to 406 error.

Make it easier to define progressive actions

currently:

var users = app.resource('users', actions);

 users.get('/foo')

is GET /users/foo, not GET /users/:user/foo as some would expect, however we do need a way to define both. I propose that users.get('/foo/bar') is /users/foo/bar, andusers.get('foo/bar')is/users/:user/foo/bar`

Default ID should be 'id', not based on name

Just spent a bunch of time debugging what turned out to be caused by us reusing some code that said req.params.id for a non-top-level resource.

IMHO, having the API change based on what resource you're in doesn't exactly meet the principle of least surprise. =D

Also, FWIW, from a usage perspective, id is a much better variable name because it's actually a string, whereas e.g. forum or w/e isn't accurate, because it's not a Forum object (or whatever my model-layer objects are).

So here's my ask for the default ID to be consistent and simple. You could still pass in a custom ID as an option, etc.

Wrong version of express-resource published on npm registry?

Hi,

I believe the npm registry contains the wrong version of express-resource. While
npm view express-resource
tells me that the version published should be ok:
{ name: 'express-resource',
description: 'Resourceful routing for express',
'dist-tags': { latest: '0.1.0' },
maintainers: 'tjholowaychuk [email protected]',
time:
{ '0.0.1': '2011-02-25T17:15:02.390Z',
'0.0.2': '2011-03-04T00:04:38.603Z',
'0.1.0': '2011-03-29T20:26:15.566Z' },
the contents of /usr/local/lib/node/.npm/express-resource/0.1.0/package/index.js seems to belong to version 0.0.2. For example, it is considerably shorter (~80 lines vs ~200 lines).

Peter

Nested Resources with Express-Namespace

When using both express-namespace and express resource, I get the following error when trying to implement nested resources:

.../node_modules/express-namespace/index.js:64
fn.namespace = curr;
^
TypeError: Cannot set property 'namespace' of undefined
at HTTPServer. (.../node_modules/express-namespace/index.js:64:20)
at HTTPServer.namespace (.../node_modules/express-namespace/index.js:29:6)
at HTTPServer.get (.../node_modules/express-namespace/index.js:57:10)
at Resource.add (.../node_modules/express-resource/index.js:188:17)
at HTTPServer. (...)
at HTTPServer.namespace (.../node_modules/express-namespace/index.js:29:6)
at ...

E.g
var forums = app.resource('forums', require('resources/forums'), { load: Forum.get });
var threads = app.resource('threads', require('resources/threads'), { load: Thread.get });

forums.add(threads);

"express": "2.5.2",
"express-resource": "0.2.4",
"express-namespace": "0.0.4",

'Mount' point for .resource()?

Is there a way - other than mounting it as a 'sub-app' - to provide a root mount point for express-resource? I want all the resources to live at /api/{resources}, but I can't seem to find a way that feels 'right' to accomplish this.

Ability to use content-negotiation only for known formats

My usecase is as follows:
I want my resource Ids/Names to be human readable, with all the special chars and dots they include.
I do have a “champions/Dr. Mundo.png”
Thanks to the patch in pull request 27, it does work now when I include a format. So “Dr. Mundo.png” becomes “Dr. Mundo”. Same for .json.

But I want to use “champions/Dr. Mundo” as URL without any appended format, showing the default html.
I could just make it “champions/Dr. Mundo.html” but I don’t want to have that ugly .html everywhere.

So I want the format to be either .png or .json, but not mess up my resource Id otherwise.

Namespaced Resources Require Specifying param

Works...

app.resource('admin/users', require('./app/resources/admin/users'), { id: 'user' });

Doesn't work...

app.resource('admin/users', require('./app/resources/admin/users'));

In the "Doesn't work..." example the param will be ":admin/user" instead of ":user".

Allow format on create (post), update (put) and destroy(delete) requests

Is there a reason why format specifier (e.g. '.json') cannot or should not be used on create, update and/or destroy requests?

Reason I ask is that I am using the format specifier to cater to various and varied "RESTful" implementations and interpretations.
i.e. support various Grids and the likes...

I have changed the line (around line number 111 of index.js):

if ('get' == method) route += '.:format?';

to:

route += '.:format?';

Initial tests show nothing has broken, and I do have a 'load' function to make sure id is extracted properly.

**Edit:
Added Destroy (delete).

some routes not working?

environment: node v0.6.6 on windows with express 2.5.2/connect 1.8.3 and express-resource 0.2.3

Routes in the form of "/users/1/edit" do not work for me (e.g. I get "Cannot GET /users/1/edit" in the browser), whether or not they are a default route (such as "edit") or a custom mapped route (such as "send" in "/users/1/send"). However the other routes seem to work fine, those in the style of "/users" or "/users/1."

Here's a gist containing the setup that fails for me: https://gist.github.com/5490fb68a61f9b80b0fa

Ordering bug

because of Object.keys() exporting .new etc are not order independent, this is definitely a bug

API question

I plan on either updating express-resource for express 3, or possibly writing a standalone resourceful router for express 3 in the meantime. What are your thoughts on an API like this?

snodgrass23/base12#14

Handle not found routes

I used to set app.all('/*', function (req, res, next) ... as my last route in order to handle routes that are not found, it used to work fine but now that I use express-resource it seems that static content like .css, .js, .jpg are processed by the router without express-resource they are not processed and app.all('/*'... handles not found routes properly

Adding custom actions to controller

To add custom actions, today I do this (similar, this is adapted so there may be some simple errors):

    var controller = require('users_controller');
    var resource = app.resource('users', controller);

    var custom_user_actions = [
      {
        name: 'login',
        method: 'get', // or post, put, delete
        scope: 'element', // or 'collection'
        action: resource.login
      }
    ];


    // Constructs /users/:user/login for element-type actions, or /users/recent (for example) for collection-type actions
    custom_user_actions.forEach(function(action) {
      var path = '';
      if('element' == action.scope) {
        path = '/' + resource.param;
      } 
      path = path + '/' + action.name;

      // Calls resource.get, etc
      resource[action.method](path, action.action);  // Add with the proper method  
    });
  }

First, is there already a better way to do this? If it makes sense, the forEach could be integrated as a method on the Resource object pretty easily. Other approaches?

customize generated urls

Not sure how possible this would be, but... It would be super awesome if there was an option to customize the generated URLs on a per-action basis. For instance, assuming we only export new, create and destroy:

app.resource('sessions', require('./sessions'), { paths: { 'new': '/login' } });

... would generate URLs that would map to actions like this:

GET     /login              ->  new
POST    /sessions           ->  create
DELETE  /sessions/:id       ->  destroy

This would be especially cool if it played nice with bodyClasses (issue #11) in such a way that bodyClasses() for '/login' would generate 'sessions new'. This would be ideal.

similarly named nested resources not provided for

This works:

    var photos = app.resource('photos', photosController)
      , posts = app.resource('posts', postsController)
      , photosComments = app.resource('comments', commentsController)
      , postsComments = app.resource('comments', commentsController);

    photos.add(photosComments);
    posts.add(postsComments);

However, I am not sure whether this will create problems down the line. Particularly because app.resources.comments will always be the last nested resource added, and the first one would not be accessible via app.resources.

custom collection actions

Suppose I've done something like:

var users = {

  show: function(req, res){
    //do something
  },

  me: function(req, res){
    //do something
  },

  load : function(id, fn){
    User.findById(id, fn);
  }
};

var userResource = app.resource('users', users);
userResource.map('get', 'me', users.me) //expecting /users/me to do something

That doesn't work. It seems to think that "me" is the ID and passes it to load, thinking it's going to invoke show. In fact, I don't know how it would know any better. So I'm thinking there's no way to do custom collection actions; you can only do custom member actions.

So first off, is that right? If so, is this something I should patch?

Project status

This is just a matter-of-fact question on the project's status before I invest a lot of effort into using it in my project. Is this project considered production quality? I was in the beginning stages of designing almost this exact thing but also with mongoose schema mapping into resources (which Panta has written that depends on this project) that would save me a month or two of work, if I don't get stuck down a rabbit hole with it. I take DRY to a whole new level - DRO or ABD (Already Been Done) ;)

Behavioral differences between RESTful rails and express-resource

When i create a restful scaffold in rails like

GET /resource/:id/edit i am greeted with a form that does a POST to /resource/:id.
But for a similar resource if i post to /resource/:id from the /resource/:id/edit form i get a Cannot POST. If this is unavailable how can a web-application update a resource via HTML form.

Thanks

Same resource nested and un-nested -> double call to auto-load

Hi,

I have two resources, Collections and Teams, that I am exposing using express-resource, like this:

var competitions = app.resource("competitions", require('./resources/competitions'));
var teams        = app.resource("teams",        require('./resources/teams'));
competitions.add(teams);

Teams is then a nested resource within it's parent competition, which is as I wanted it to be. However, I also wanted teams to be accessible as it's own resource. In other words, like this:

/competitions/:id/teams/:id
/teams/:id

So, to get this I changed the code as follows:

var competitions = app.resource("competitions", require('./resources/competitions'));
var teams        = app.resource("teams",        require('./resources/teams'));
competitions.add(teams);
teams = app.resource("teams", require('./resources/teams'));

I don't know if this is the way it is supposed to be set up, but this actually works. There is only one small problem. I have an auto-load method setup for the team-resource, and when I access the /teams/:id resource it actually ends up calling the auto-load twice. I guess that somehow it fires for both the teams/.id and the competitions/:id/teams/:id resource?

Any ide on how to avoid this from happening?

POST/PUT/DELETE -> Forbidden

Hello, POST/PUT/DELETE always return Forbidden, GET methods works fine... I tried to use the example

exports.index = (req, res) ->
  res.send "forum index"

exports["new"] = (req, res) ->
  res.send "new forum"

exports.create = (req, res) ->
  res.send "create forum"

exports.show = (req, res) ->
  res.send "show forum " + req.params.api

exports.edit = (req, res) ->
  res.send "edit forum " + req.params.api

exports.update = (req, res) ->
  res.send "update forum " + req.params.api

exports.destroy = (req, res) ->
  res.send "destroy forum " + req.params.api

I used api resource name instead of forum for my test

So index,new,show,edit worked fine but create,update,destroy throw me Forbidden :/

Access resource and action name from request handler

Is there a way to to access the resource name and/or action from inside the request handler? e.g.

// app.js
app.resource('user', require('./users.js'));
// users.js
exports.index = function(req, res) {
  var resource = req.resource;
  var action = req.action;
  res.render(resource + "/" + action);
}

TypeError: Cannot read property 'methods' of undefined

Hi

I am using
Express -- [email protected] and [email protected] on WinXP

When I require express-resource as require('express-resource')

I get the following error

TypeError: Cannot read property 'methods' of undefined
at Object. (D:\some-folder\node_modules\express-resource\index.js:234:15
)
at Module._compile (module.js:441:26)
at Object..js (module.js:459:10)
at Module.load (module.js:348:31)
at Function._load (module.js:308:12)
at Module.require (module.js:354:17)
at require (module.js:370:17)
at Object. (D:\some-folder\news-rest-server.js:7:15)
at Module._compile (module.js:441:26)
at Object..js (module.js:459:10)

'del' is deprecated

app.del is being used for the destroy route, but .del has been deprecated since Express 4.2 - it still exists, but it should be removed. I couldn't tell from the README, but are you intending to explicitly support 4.*?

Happy to make the change, just would like to know your approach.

What's the opts argument in resource() for?

Hi,

I looked thru express-resource/index.js and wondered what happens if I pass an object as third argument in express.HTTPServer.prototype.resource() function.

Each property in opts is copied to options, which is a local variable, at line 259 in index.js.
However, neither opts nor options are passed to the Resource object. The opts argument seems useless.
The comment above resource() doesn't mention the opts at all.
Is this reserved for future functionality?

Thank you,
Bow

getting intermittent '502 bad gateway error'.

We are using nodejs(v 0.10.29 ) ,express,nginx( version 1.4.6) with mongodb(v 2.6.3) replicaset and getting intermittent 502 bad gateway error. pm2 logs is unable to log error though nginx aerror.log is showing

recv() failed (104: Connection reset by peer) while reading response header from     upstream, client: xxx.xxx.xxx.xxx, server: somedomain.com, request: "GET /img/abc.png HTTP/1.1", upstream: "http://127.0.0.1:3000/img/abc.png", host: "domain.com", referrer: "http://domain.com/admin/"

and access.log is saying:

"GET /url/abc.html HTTP/1.1" 502 723 "http://domain.com/admin/" "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36"

can anyone guide me with the issue?

refactor route remove()

this is a tracking ticket for a known issue between HEAD of this and express. running the test suite reveals the issue. tj knows the fix. patch coming!

bodyClasses dynamic helper

It would be nice if generating a resource, like below, would create a dynamic helper for the view. This would be super useful for styling specific pages.

app.resource('forums', require('./forum'));
exports.index = function(req, res){
  res.send('forum index');
};
// bodyClasses() //=> 'forums index'

exports.new = function(req, res){
  res.send('new forum');
};
// bodyClasses() //=> 'forums new'

exports.create = function(req, res){
  res.send('create forum');
};
// bodyClasses() //=> 'forums create'

exports.show = function(req, res){
  res.send('show forum ' + req.params.id);
};
// bodyClasses() //=> 'forums show'

exports.edit = function(req, res){
  res.send('edit forum ' + req.params.id);
};
// bodyClasses() //=> 'forums edit'

exports.update = function(req, res){
  res.send('update forum ' + req.params.id);
};
// bodyClasses() //=> 'forums update'

exports.destroy = function(req, res){
  res.send('destroy forum ' + req.params.id);
};
// bodyClasses() //=> 'forums destroy'

change 'new' to 'store'

maybe will good to change 'new' to 'store', because will causing conflict with 'new' keyword?

var orderedActions = [
   'index'    //  GET   /
  , 'create'  //  GET  /
  , 'store'     //  POST   /store
  , 'show'    //  GET   /:id
  , 'edit'    //  GET   /edit/:id
  , 'update'  //  PUT   /:id
  , 'patch'   //  PATCH /:id
  , 'destroy' //  DEL   /:id
];

Nested resources autoload callback

I have a task nested in a list, and the task ID is dependent on the list. The list is auto-loaded, but I can't get access to the list in the task auto-loader because it doesn't receive the request. Is there a more elegant solution, or can/should we pass req down through the auto-load callback?

Imposible to get float params from url string

Example map:

thingsResource.map('get', '/:min/:max', thingsRouts.getMinMax)

Min and max is float.
I'm making 'get' request to url: things/12.22/12.45 or things/12.22/12.45/
I expected: req.params.min = 12.22 and req.params.max = 12.45, but i get: req.params.max = 12 and req.params.format = 45 instead

Easy workarouund is just make request like: things/12.22/12.45. <- this point is required.

Sorry for my bad english :)

adding paths?

Hi,
following the sample:
var forums = app.resource('forums', require('./routes/forums'));
I can do:
curl -i localhost:3000/forums
how to put the forums behind a path, say:

curl -i localhost:3000/api/forums
?
possible?

angelo

Allow Passing in Route Middleware on Resource

It would be nice to be able to set route middleware. Specifically, when mapping the users resource:
var user = app.resource('users', require('./user'));

It would be great to do something like:

var user = app.resource('users', require('./user'), { before: authenticateUser });

which is would be the equivalent of
app.get('/users', authenticateUser, require('./user').index);

req.session undefined

I noticed that req.session is undefined for resources but it works fine for manually added routes using app.get method

{ lastAccess: 1329521660742,
  cookie: 
   { path: '/',
     httpOnly: true,
     _expires: Sat, 18 Feb 2012 03:34:20 GMT,
     originalMaxAge: 14400000 },
  _csrf: 'B91I4oOdFYhs3h9PNdBsJagE' }

  GET /404
  response time: 20ms
  memory rss: 148.00kb
  memory vsize: NaNgb
  heap before: 29.63mb / 107.27mb
  heap after: 30.42mb / 107.30mb

undefined

  GET /
  response time: 9ms
  memory rss: 0b
  memory vsize: NaNgb
  heap before: 18.28mb / 52.08mb
  heap after: 18.85mb / 52.08mb

/ is set through app.resource and /404 is set through app.get

load does not have access to request for other auto-loaded variables

In the example /forums/5/threads/12 the 'forum' can be loaded in the auto-loading load method. In the load method for a 'thread' there's no way to access the already loaded 'forum' - which could contain either neccesary information to load the 'thread', or could in fact contain the 'thread'.

At the moment, the load method should look like function (id, callback) {} I don't see the need for passing the id value, rather than the request. It only hides the key to the param containing the id. I realise that changing the arguments for this would break existing implementations and add a line of code to these implementations, e.g. var id = req.params.forum;, but I can't see another way.

Unimplemented methods should return 405 status code

Currently HTTP requests to a resource that specify a method unimplemented by that resource return a 404 Not Found status code. That is misleading, since the resource can be found—it just doesn't allow that method. It should return a 405 Method Not Allowed in this case.

This behavior (or at least the "Cannot [METHOD] [PATH]" message") seems to be coming from the connect lib; it's not clear to me whether it can or should be fixed there, or in express-resource.

Compatibility with Express 3

I'm currently using express 3.0.0alpha1-pre (ok, i know it's alpha) and express-resource 0.2.4 (from npm)
As soon as I require express-resource i get this error:

TypeError: Cannot read property 'methods' of undefined
    at Object.<anonymous> (/home/myUser/web/myWebsite/private/node_modules/express-resource/index.js:234:15)

That line refers to the following code block

express.router.methods.concat(['del', 'all']).forEach(function(method){
  Resource.prototype[method] = function(path, fn){
    if ('function' == typeof path
      || 'object' == typeof path) fn = path, path = '';
    this.map(method, path, fn);
    return this;
  }                                                                                                                                                   
});

My main question is: Are you planning to make express-resource compatible with Express 3, if so, do you have any ETA?
Thanks for your time =)

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.