senecajs / seneca-web

Http route mapping for Seneca microservices.
MIT License
76 stars 44 forks source link

add usemethod to the wildcard mapping object #81

Open k2s opened 8 years ago

k2s commented 8 years ago

Similar to useparams and usequery following code

seneca.act('role:web', {use:{
  prefix: '/api',
  pin:    'role:api,cmd:*',
  map: {
    echo: {GET:true, POST:true, suffix:'/:foo', usemethod: 'methodName'}
  }
}})

would merge methodName:get into the arguments for the Seneca action if the request is GET and methodName:post if it is POST method.

mcdonnelldean commented 8 years ago

@k2s I think I may be missing suffix from the new implementation. I'll get it added back before release. Can you give me a use case for the above?

k2s commented 8 years ago

for given map I could separate implementation by Seneca patterns:

seneca.add('role:api,path:echo,methodName:get', impl.echoGet)
seneca.add('role:api,path:echo,methodName:get', impl.echoPost)

currently I have to either do if or call Seneca again with added method parameter inside role:api,path:echo.

mcdonnelldean commented 8 years ago

Oh ok,

So you now get the route meta via msg.args so you could branch on in your main handler based on if it is post or get.

Having said that. I like the idea of being able to suffix the pattern. I don't like the idea of making it the method as that ties down the pattern to a route but it would be easy to add a general suffix that is simply tacked on to the handler. This would allow you do the above.

Having said that, it might not work great with Hapi, let me investigate more over the next week.

mcdonnelldean commented 8 years ago

Ok I think what would work better here having played with it is some form of substitution. The pin would become pin:{map},someKey:{method}. That would be a cleaner implementation.

CC @tswaters Thoughts on the above?

tswaters commented 8 years ago

So the desire here is to have the following actions defined - both of which can be triggered from the same route map?

seneca.act('role:api,path:echo,method:get', (msg, cb) => {
  // only fires on GET
})
seneca.act('role:api,path:echo,method:post', (msg, cb) => {
  // only fires on POST
})

Where the method component of the pin has been defined by usemethod property in the map, if it has been provided.

Can you provide more details on how you see the substitution working? Are you saying it should be possible to include other components of the request as part of the string in addition to method? How do you see that working?

mcdonnelldean commented 8 years ago

@k2s @tswaters Lets sit on this for a bit. It won't work with Hapi since hapi is 1 route per array of gets. This means it would have to be something supported at the adapter level. I don't want to make any changes there until it's decided if the adapters are internal or external.

@tswaters In my line of thinking above you would only have two special keys {map} which maps the the name and replaces * and {method} which gets replaced by the method name. This would allow you to substitute any key for either of those two values. The substitution would be easily done with a regex.

The concern I have right now the current logic is based on 1 handler per key. This would make it one handler per key per method. It requires more thought around if it is actually usable.