citizennet / purescript-httpure Goto Github PK
View Code? Open in Web Editor NEWA web framework written in PureScript.
License: MIT License
A web framework written in PureScript.
License: MIT License
When computing the value for the Content-Length header, String.length
is used. This is not correct for non-ASCII strings, as each character gets encoded to two or more bytes in UTF-8. For example, when using the string "äö"
as the response body, there's Content-Length: 2
but the content is actually 4 bytes long.
We should be calculating the Content-Length header based on the size of the response.
Go through guides and update based on changes since the last release, and double check that all examples are still accurate
Body
typeclass, along with different instances (String
, Buffer
, Stream.Readable
, etc)Content-Length
, etc) and mechanism for overridingpurescript-routing
, etc)purescript-node-http
has a large surface area, and much of the functionality is currently unavailable through purescript-httpure
. We should ensure that all functionality available through purescript-node-http
is exposed somewhere in purescript-httpure
.
We need better sad-path handling. Things like:
This will also significantly simplify the example code, as it will allow us to reuse the same port for all examples
Currently, we only have HTTP support. We should add HTTPS support.
Serving e.g. image data is not currently possible because response body is always a UTF-8 encoded string.
See thread here
I believe that we should be using forkAff
when running the router. We should investigate implications of doing that.
Currently only ResponseM
is re-exported, but Response
is not.
Currently, routing only matches exact strings. We should implement parameters, optional segments, etc.--we should support what express.js supports.
Most usage of Foreign.Object
should be using Map
from https://github.com/purescript/purescript-ordered-collections instead of using Foreign.Object
. Current usage is for query parameters and headers.
Add first round of unit/integration tests.
Should take a path, automatically read and buffer the file, and automatically set the Content-Type
response header.
The fields are already expected of all routes but are not actually written out currently.
Some places in the codebase don't follow purescript style convention. That should be cleaned up.
Currently Route
is a data constructor, and routes are created like:
routes = [
{ method: Get, route: "/hello", handler: helloHandler },
{ method: Post, route: "/goodbye", handler: goodbyeHandler }
]
A better API would be to have Route
have data constructors for each HTTP method, and construct routes something like:
routes = [
(Get "/hello" helloHandler),
(Post "/goobye" goodbyehandler)
]
This may or may not be something we want to do. Express supports websockets, but I'm not convinced that HTTPure should--WS is a very different protocol than HTTP or HTTP/2 and I'm not sure that HTTPure should cater to those differences.
Likely some other framework should be implemented outside HTTPure to support websockets in PureScript, but this ticket remains open as an investigation until we've decided for sure if we do or do not want to support WS.
Currently the execption propagates through the stack. HTTPure should be exception-free, so we should handle this.
We should have the ability to run middleware before or after the routes are executed.
Must support HTTP 1.1 chunking
Query
and Status
are missing in the top-level HTTPure module.
ServerM
(and HTTPureM
) has no need for the FS
effect. It's only there for reading the key and cert files for secure servers. It would be better to have a SecureServerM
type separated from the ServerM
type, which pulls in the FS
effect.
The current API for matching path segments is entirely built around the Lookup
typeclass. This works, but it can get clunky for some common things. For example, you can do this:
router :: HTTPure.Request -> HTTPure.ResponseM
router request@{ path }
| path !@ 0 == "something" = somethingRoute request
| otherwise = HTTPure.notFound
But that will send any request whose first segment is "something"
to somethingRoute
. Likely the intent is to only send the request to somethingRoute
if it has exactly one segment, which is "something"
, and you'd have to do something like this:
router :: HTTPure.Request -> HTTPure.ResponseM
router request@{ path }
| path !@ 0 == "something" && length path == 1 = somethingRoute request
| otherwise = HTTPure.notFound
The API can become very painful as you have longer paths, e.g.:
path !@ 0 == "something" && path !@ 1 == "anotherThing" && path !@ 2 == "somethingElse" && length path == 3
And that doesn't even include doing things like enforcing specific requirements for certain pattern-based path segments, which requires significantly more complexity.
router :: HTTPure.Request -> HTTPure.ResponseM
router request@{ path }
| path =~ "/something" = somethingRoute request
| path =~ "/foo/\d+" = fooRoute request
| path =~ "/something/anotherThing/somethingElse" = ...
| otherwise = HTTPure.notFound
Introduce two new binary operators, =~
and ==~
. These operators take a Path
on the left side, and a String
on the right side. The Path
will be matched against the String
using some set of rules heavily inspired by Express's routing engine. =~
will be used for case-insensitive routing, where ==~
can be used for strict (case-sensitive) routing.
The only real change I'm aware of over what express does is that we'll have to come up with a different API around route parameters. Of course, that could be as simple as replacing :namedParameter:
with \w+
and using Lookup
to reference the parameters. If there were some way to even use the named parameters approach that Express uses, it would be awesome, but I don't see how that would be possible in a purely functional world (at least, without introducing a significantly more complex API, which isn't really worth it--it's a fairly small thing, and if it can't be done without an overly complex API, it's not worth changing to it).
In the interest of centralizing dependencies and preparing to be able to be native-compiled, we should centralize and abstract purescript-node-http
uses so that it can be easy to swap out http backends when necessary.
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.