Code Monkey home page Code Monkey logo

purescript-wai's Introduction

License CI


WAI: Web Application Interface

English   日本語   Français  

This library provides a common interface for communication between web applications and web servers.
WAI cannot be used standalone, it requires a server handler such as warp.

Table of Contents

Installation

This library is not yet published to pursuit.
You can install this package by adding the details below to your packages.dhall:

Using Spago
let additions =
  { wai =
      { dependencies = [ "aff", "effect", "http-types", "node-net" ]
      , repo =
          "https://github.com/Woody88/purescript-wai.git"
      , version =
          "master"
      }
  , http-types =
      { dependencies = [ "tuples", "unicode", "generics-rep" ]
      , repo =
          "https://github.com/Woody88/purescript-http-types.git"
      , version =
          "master"
      }
  }
user@user:~$ spago install wai

Application

WAI models applications using a request-response flow.

type Application = Request -> (Response -> Aff ResponseReceived) -> Aff ResponseReceived

An application is a function that receives a request along with a continuation function for sending the response.

Middleware

Middleware is an application transformer. That is, a function from application to application:

type Middleware = Application -> Application

Because these are simply functions, they can be composed in any order.

middlewares :: Middleware 
middlewares = myCustomMiddleware1 >>> myCustomMiddleware2

myCustomMiddleware1 :: Middleware 
myCustomMiddleware1 app req send = ...

myCustomMiddleware2 :: Middleware 
myCustomMiddleware2 app req send = ...

This enables us to write declarative, composable middleware:

requireAuthToken :: Middleware 
requireAuthToken app req send 
    | hasAuthToken req = app req send 
    | otherwise        = send $ responseStr unauthorized401 [] "Missing Token!"
    where 
        hasAuthToken :: Request -> Boolean
        hasAuthToken req = ...

-- Creates a `Response` from a string. This helper function is provided by WAI. 
responseStr :: Status -> ResponseHeaders -> String -> Response

Contributing

If you are interested in fixing issues and contributing directly to the code base, please see the contributing guidelines.

Changelog

Change log details can be found here

License

Licensed under the MIT license. Copyright (c) 2021 Woodson Delhia. All rights reserved.

purescript-wai's People

Contributors

jordanmartinez avatar robertdp avatar woody88 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

purescript-wai's Issues

Consider merges with other, preexisting wai libs

I think that these libs can be seen as really valuable source of types and solutions - especially @julienchan lib:

https://github.com/julienchan/purescript-node-wai

https://github.com/matthieubulte/purescript-wai

If you consider moving this lib to the purescript-node-contrib and we want to establish some sort of a standard here then probably we should consider merging some parts from there and also push into tighter collaboration as we are still a really tiny community and there is no space for such a separation I think ;-)
What do you think?

Provide backend-specific types and use row polymorphism everywhere else

Given that Request includes a backend-specific request object, it might be better to redefine that type via row polymorphism:

newtype Request otherRows
    = Request { method          :: H.Method 
              , rawPathInfo     :: String
              , httpVersion     :: H.HttpVersion
              , rawQueryString  :: String
              , requestHeaders  :: H.RequestHeaders
              , isSecure        :: Boolean
              , remoteHost      :: String 
              , pathInfo        :: Array String 
              , queryString     :: Object String 
              , body            :: Aff (Maybe Buffer)
              , bodyLength      :: RequestBodyLength
              , headerHost      :: String 
              , headerRange     :: Maybe String 
              , headerReferer   :: Maybe String 
              , headerUserAgent :: Maybe String
              , rawHeader       :: Maybe Buffer
              | otherRows
              }

newtype RequestNodeJs =
  RequestNodeJs (Request (nodeRequest :: Maybe HTTP.Request))

defaultRequest would need to be changed. There's two ways:

  • change it to a RecordBuilder API, so that one can build it
  • specify a backend-specific one for each

Make HttpRequest not be bound to Node's HTTP Request

Hi @Woody88 !

I'm building backends that utilize AWS api gateway and Lambda. Basically that simply involves creating the ff:

newtype ApiGwHandler
  = ApiGwHandler (EffectFn2 ApiGwReq LambdaContext (Promise ApiGwResp))

Note that ApiGwReq, LambdaContext and ApiGwResp are all just records broadly described here:

https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html

I'd love to be be able to use purescript WAI to get a bit more generalization. Current problem is WAI.HttpRequest is defined to newtype node's http request.

If it were a regular record, it would be simple for me to write a simple ApiGwReq -> WAI.HttpRequest and make this usable on AWS lambda.

On the Response side, it's going to be a bit of a shame since from what I can tell, on AWS API GW/Lambda, I need to output a fixed string (possibly base 64 encoded) for the body. So I'll simply evaluate all the Response type to that.

As an aside, we've been deploying on AWS lambda/api gateway while developing locally by simply having an express server execute the EffectFn2 mentioned above. I'd love to replace the latter with purescript-warp. And once I have a wai binding for AWS lambda then we'll transition our backend to that as well. :)

Laziness vs Strict issues?

Since Haskell is lazy by default, they can have a lot of fields in their Record type for Request. If we port their model 1-to-1, will there be performance issues for doing that?

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.