Comments (7)
Folks, the feedback here is really helpful, thank you both for leaving those opinions @akheron and @paluh . You guys have convinced me, there are enough tools out there that can be used and the simplicity of HTTPure is valuable. I'll close this ticket as something that doesn't need to happen.
I do think before we go to 1.0 it would be nice to do a better job documenting some common patterns around routing, such as the array pattern matching approach, and using tools like the ones you listed @paluh . I'll add a note in #106 to remember to do that.
Thanks again all!
from purescript-httpure.
@akheron I've put a lot of thought into this issue, I'm not quite convinced on the proposed solution and would love to get feedback/ideas, so if you have any to give, it would be much appreciated!
from purescript-httpure.
I've used array pattern matching to accomplish good ergonomics, and I think it's the way to go. It solves matching the path and capturing parameters at the same time.
Matching path only:
router { path } =
case path of
["todos", id] -> readTodo id
["todos"] -> listTodos
[] -> frontPage
_ -> HTTPure.notFound
Matching path and method:
router { method, path } =
handle method path
where
handle HTTPure.Get ["todos", id] -> readTodo id
handle HTTPure.Put ["todos", id] -> updateTodo id
handle HTTPure.Get [] -> frontPage
handle _ [] -> HTTPure.methodNotAllowed
handle _ _ -> HTTPure.notFound
from purescript-httpure.
That's what I was originally leaning towards, but I started thinking more along the lines of the express API, because working on array pattern matching is somewhat limited in a few ways. Specifically:
- We can't match on specific ID shapes (
/todos/\d{4}-\d{6}
--contrived but a lot of use cases do build IDs that have specific shapes). - We can't deal in variable-length segments. For instance, in Express, you could match something like
(/:locale:)?/todos/:id
. - Doing anything involving requiring regexes immediately becomes a non-ergonomic API.
I'm not entirely convinced these 3 are significant problems--they all have workarounds, and it may be cleaner to defer to the workarounds than to move away from PS language features.
For 1., the workaround is just to match on any shape and check the shape in the route handler. I just don't love that, because it means that some aspects of routing are moved out of the router, but it works. For 2, you just have to have two different matches, one for each case--not a huge deal. 3 is a gross API, but totally doable--and perhaps not something we should cater towards, since HTTPure I think should make everything possible, but should make good things easy, and I can't think of a case where complex regex path matching would ever be a good thing.
So I guess the question is, at this time, do you feel that any of these 3 are significant enough limitations (or that the workarounds are gross enough) to be worth catering solutions?
from purescript-httpure.
Oh, and one other problem with array pattern matching: you can't do case-insensitive matches. That isn't a big issue for something like a REST API, but it's a non-starter for something that serves, e.g., a UI, where addresses are entered by users into address bars in browsers. HTTPure should be able to cater to both use cases. I don't know of any good workaround here, other than making all routes use regexes, which gets back into the gross ergonomics situation.
from purescript-httpure.
The thing I like most in HTTPure is that the serve takes a function that processes all requests. The user is free to implement routing, request handlers, middleware etc. in any way he sees fit. However, providing helpers for common use cases (e.g. routing) would be a big plus, so that each user doesn't have to reinvent the wheel.
I suggest figuring out the best way to create composable routers, which could then be used for different purposes. If the user wants regex route matching, it could be used while also using plain array pattern matching or simple prefix matching for other purposes.
In purescript-httpure-rest-router
I approached the problem like this: https://github.com/cprussin/purescript-httpure-rest-router/blob/f8883ba2cc95646ead3933ec7bce8a12b9fc6b90/examples/Todo.purs#L105-L119
The only problem with those arrays of routes and making a router function using Router.router
is that routers made like this are not composable, i.e. the router always returns a response even though none of the routes matches (falling back to 404).
PS. Case-insitive matching could be accomplished by e.g. converting the path of some or all requests to lowercase in a middleware function.
from purescript-httpure.
Hi,
I'm not sure if I should add any comments as I'm not a contributor but barely a user (we have just started to build a service around httpure)... but anyway here are my two cents:
I really like clean API which is provided by this framework and I think that advanced/opinionated routing options should be delegated to external libraries like: purescript-httpure-rest-router, purescript-routing, purescript-routing-duplex, purescript-boomboom, purescript-boomerang or some other (maybe "contrib") proposition.
Routing can be done in different ways and with different focus in mind. If you are building API you can lean toward performance and simplicity and don't need bidirectional routes, if you are implementing a web service you probably don't want to hard code any urls in your HTMLs and want some automatic serialization for your typed routes etc.
I think that your path representation as just an array of segments is nearly ideal as it is lightweight, covers really simple scenarios and can be base for integration with any other more advanced routing option...
Thanks for your work on httpure!
from purescript-httpure.
Related Issues (20)
- How to handle `Expect: 100-continue`? HOT 2
- Upgrade dependencies
- Expose request path and query to enable custom route parsing? HOT 7
- Should functions on `Response` return `MonadAff m => m Response` HOT 1
- Persist mutable state between requests HOT 6
- default `serve` binds to `localhost` (resulting in "connection refused" errors) HOT 6
- Allow multiple SetCookie headers in response HOT 22
- Make `Status` a bit more safe and signature friendly HOT 1
- Change `Method` representation to something more like `Status` HOT 1
- Pursuit is not up to date with 0.10.0 HOT 2
- Utils.replacePlus Only Replaces the First Occurrence HOT 1
- Body write doesn't wait for async finish? HOT 4
- Add support for multiple request body formats
- Simplify & update project setup
- No 'Body' instance for 'Duplex' streams
- Calling `HTTPure.Body.toString` multiple times on the same Readable stream blocks forever HOT 6
- Is HTTPure production ready? HOT 14
- PureScript 0.15-compatible release. HOT 3
- Parse cookies
- build errors HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from purescript-httpure.