alexdavid / exprestive Goto Github PK
View Code? Open in Web Editor NEWA RESTful routing middleware for Express.js (and other connect-based web frameworks)
License: MIT License
A RESTful routing middleware for Express.js (and other connect-based web frameworks)
License: MIT License
Referencing a controller that doesn't exist in a routes file returns the error
TypeError: Cannot call method 'replace' of undefined
Better error messages all around would help debugging when using exprestive magic.
@charlierudolph and I discussed #16 and came to the conclusion that while rails has magic around models, Exprestive should just be a routing library and therefore reverse routes need to be different for each action, and they should also return the method for form helpers to use.
This is the syntax we discussed:
paths.user(123)
would still return a string to the reverse route /users/123
paths.user(123).method
would return a string of the http methodThis can be achieved with non-primitive strings:
str = new String '/users/123'
str.method = 'GET'
This way, as charlie mentioned, users of this library can easily implement a form helper:
//- form_helper.jade
mixin form(path)
form(action=path, method=path.method)
if block
block
//- index.jade
+form(paths.users(123))
@jondistad @kevgo please let me know what you think
@routes
is set to the hash of reverse routes in controllers, but it would be great if middleware functions specified by controllers could have this bound to the controller instance so that @routes
is available
Thoughts, @charlierudolph ?
It appears the middleware that sets res.locals.routes isn't called until after exprestive calls the controller action. Thats why the feature tests passes but this fails in production.
The feature specs are more expressive if you provide direct examples for the systems under test.
Like this:
Given a routes file defining
"""
GET /users Users#index
POST /users Users#create
"""
And the following controller
"""
class UsersController
index: (req, res) ->
res.end 'hello world'
"""
When I make a request to "/users"
Then I receive a response with code: 200 and body: "hello world"
The multi-line strings are provided to you as a variable, similar to tables: http://cukes.info/step-definitions.html
You can use something like https://github.com/originate/kappamaki#attributes_from_sentence to parse complex sentences into a hash. Sorry no JS version yet, but should be trivial to build.
This makes it much easier to see the syntax of routes etc, and also to iterate it during development.
module.exports = ({GET, scope}) ->
scope '/abc', ->
GET 'def', to: 'abc#def'
GET 'ghi', to: 'abc#ghi'
GET 'jkl', to: 'abc#jkl`
equivalent to
module.exports = ({GET}) ->
GET '/abc/def', to: 'abc#def'
GET '/abc/ghi', to: 'abc#ghi'
GET '/abc/jkl', to: 'abc#jkl`
so the scope just gets prepended (with a trailing slash) to any routes defined under it
Allow export default
with classes
Since browsers don't support PUT
or DELETE
except in XHR, if exprestive receives a POST
request with the _method
variable set to PUT
or DELETE
, it should route appropriately.
Hi, I would just like to know if I could use *.js files instead of *.coffee files ? If yes, can you shed some light on how can i do that.
Right now we have imitated Rails' OO structure and require the controllers in Exprestive to be classes. I'm wondering if this is really necessary. Why can't we simplify them to:
module.exports =
index: (req, res) ->
res.render 'users/index'
new: (req, res) ->
res.render 'users/new'
...
Making controllers classes is a misguided application of OO in my opinion. We don't really need independent objects here. There is no data and no behavior to encapsulate here. We don't need polymorphism. Unlike objects, controllers must be completely stateless and immutable. Summing this up, controllers are much more functional in nature than they are OO. They take a request as input, calculate a response (using external services), and send a response as output.
OO makes sense on the domain model level, but not for controllers or views.
Doing this also allows us to get rid of a requirement that the class name has to match the controller name. There is no more class name. The route foo#bar
maps to the controller function keyed as bar
in the file foo_controller.coffee
.
We'd like to be able to scope some middleware functions to authenticate for a group of routes. Right now to do that we would have to add middleware to each controller or break out of exprestive to run middleware for a given set of scoped routes.
I'd like to be able to do something like this:
module.exports = ({ GET, scopeWithMiddleware }) => {
scopeWithMiddleware('/api', {to: 'auth#validate'}, () => {
GET('/users', {to: 'users#index'});
GET('/widgets', {to: 'widgets#index'});
});
};
maybe there's a way to also handle cases were the middleware is just a function and not a class. Perhaps just requiring it and handing it off?
const validate = require('./middleware/validate')
module.exports = ({ GET, scopeWithMiddleware }) => {
scopeWithMiddleware('/api', {to: validate}, () => {
GET('/users', {to: 'users#index'});
GET('/widgets', {to: 'widgets#index'});
});
};
Point this.routes
to the reverse routes object in controllers, even if a custom routes object is provided.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.