Giter Site home page Giter Site logo

purescript-httpure's People

Contributors

akheron avatar arthurxavierx avatar boygao1992 avatar cprussin avatar dependabot[bot] avatar dretch avatar drewolson avatar jans-fp avatar joneshf avatar nsaunders avatar paluh avatar realvictorprm avatar rnons avatar stijnruts avatar thomashoneyman avatar tmciver avatar

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

purescript-httpure's Issues

Implement full routing

Currently, routing only matches exact strings. We should implement parameters, optional segments, etc.--we should support what express.js supports.

Add a more ergonomic API around path segment matching

The Problem

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.

Proposed Solution

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).

Add `sendFile` helper

Should take a path, automatically read and buffer the file, and automatically set the Content-Type response header.

Determine if we want websockets support

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.

Investigate `forkAff`

I believe that we should be using forkAff when running the router. We should investigate implications of doing that.

Provide a way to stop serving

This will also significantly simplify the example code, as it will allow us to reuse the same port for all examples

Better error handling

We need better sad-path handling. Things like:

  • Request closed by client while in flight
  • Exception while running router
  • Others?

Update guides

Go through guides and update based on changes since the last release, and double check that all examples are still accurate

  • Add notes on Body typeclass, along with different instances (String, Buffer, Stream.Readable, etc)
  • Add notes on default headers (Content-Length, etc) and mechanism for overriding
  • Add some notes on common path matching techniques and tools (things like array pattern matching, dealing with case sensitivity, purescript-routing, etc)

Wrap all node-http methods

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.

Implement HTTPS

Currently, we only have HTTP support. We should add HTTPS support.

Make route methods be separate data constructors.

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)
]

Content-Length header is wrong for non-ASCII bodies

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.

Abstract node-http so it can be swapped

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.

Separate SecureServerM from ServerM

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.

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.