Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapter for express js middleware #5

Closed
srghma opened this issue May 25, 2020 · 3 comments · Fixed by #8
Closed

Adapter for express js middleware #5

srghma opened this issue May 25, 2020 · 3 comments · Fixed by #8

Comments

@srghma
Copy link

srghma commented May 25, 2020

For example hyper has mkMiddlewareFromForeign method

purescript-hyper/hyper#47 (comment)

Is the same possible with warp?

@Woody88
Copy link
Owner

Woody88 commented May 25, 2020

Hi @srghma,

Yes, it's actually a great idea! warp is built as a handler for wai, so as long as you can get the express middleware to match the Application type. It should be possible. So, we could make a wai-express-js middleware. Have a look at this https://github.com/Woody88/purescript-wai-websockets.

I will try to look more into it later on.

@Woody88
Copy link
Owner

Woody88 commented Jan 4, 2021

@srghma Sorry it took me a bit of time to get on this issue. I was focusing more on my other library (purescript-swerve). So, I implemented a solution that can allow you to add express middleware using purescript-vault.

Here is a working example using express static.

Main.js

const serveStatic = require('serve-static')

exports._serveStatic = serveStatic('public')

Main.purs

import Prelude

import Data.Maybe (Maybe(..))
import Data.Tuple.Nested ((/\))
import Data.Vault as V
import Effect (Effect)
import Effect.Class.Console as Console
import Network.HTTP.Types (ok200)
import Network.HTTP.Types.Header (hContentType)
import Network.Wai (Application, Middleware, responseStr)
import Network.Warp.FFI.Server (ForeignApplication, HttpHandles, httpHandlesKey, mkMiddlewareFromForeign)
import Network.Warp.Run (runSettings)
import Network.Warp.Settings (defaultSettings)
 
main :: Effect Unit
main = do 
  let beforeMainLoop = Console.log $ "Listening on port " <> show defaultSettings.port
  httpKey' <- httpHandlesKey  -- creates key that will allow the middleware to access node HTTP request and response object
  void $ runSettings defaultSettings { beforeMainLoop = beforeMainLoop, httpKey = Just httpKey' } 
       $ serverStatic httpKey' 
       $ app 

app :: Application 
app req f = do
    f $ responseStr ok200 [(hContentType /\ "text/plain")] "Hello World!"

serverStatic :: V.Key HttpHandles -> Middleware 
serverStatic k = mkMiddlewareFromForeign k _serveStatic

foreign import _serveStatic :: ForeignApplication

Let me know if you need more details. I will be working on polishing warp's codebase and docs soon.

@robertdp
Copy link
Contributor

robertdp commented Jan 5, 2021

My PR simplifies this even further, and httpKey creation and setting is no longer required.

mkMiddlewareFromForeign :: ForeignMiddleware -> Middleware

The serveStatic example becomes:

main :: Effect Unit
main =
  void
    $ runSettings defaultSettings
    $ serveStatic "public"
    $ app

app :: Application 
app _ send = send $ responseStr ok200 [(hContentType /\ "text/plain")] "Hello World!"

foreign import _serveStatic :: String -> ForeignMiddleware

serveStatic :: String -> Middleware 
serveStatic = mkMiddlewareFromForeign <<< _serveStatic

@Woody88 Woody88 mentioned this issue Jan 8, 2021
@Woody88 Woody88 closed this as completed in #8 Jan 8, 2021
Woody88 added a commit that referenced this issue Jan 8, 2021
* Added feature for foreign middleware #5

* Changed Vault approach for simpler middleware (#7)

* Changed Vault approach for simpler middleware

* Removed extra space

* Removed HttpHandles

* Update ci.yml

* Fixed import

Co-authored-by: Robert P <robertdp@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants