Global Resources in PureScript(for AWS Lambda)












1














I would like to run PureScript code in AWS Lambda. Normally, if a lambda function has to call the database, the connection is stored in a global variable. Excuse me if the following JavaScript code is syntactically wrong as I don't write JavaScript but something like below is what I want(this is the code expected by AWS Lambda):



function createConnection() {
connection = SomeDBLibrary.createConnection(username, pwd)
return connection;
}
global.db_connection = createConnection();

handler = (event, context, callback) => {
// TODO use global.db_connection here to call the database
};

module.exports {
handler: handler
};


How do I write the equivalent PureScript to get such code? Currently, I call the createConnection() function in each of my CRUD methods which is wasteful.



Edit 1:



My actual PureScript code is below. The function which I want to call only once is aPool. However, I believe it's being called everytime one hits the /list endpoint. I would like it to be hit only once when the handler is loaded for the first time.



module Main where

import Prelude hiding (apply)

import Data.Bifunctor (lmap)
import Data.Either (Either)
import Database.Postgres (Client, ClientConfig, ConnectionInfo, Pool, Query(Query), connectionInfoFromConfig, defaultPoolConfig, mkPool, query_, withClient)
import Effect (Effect)
import Effect.Aff (Aff)
import Effect.Aff.Class (liftAff)
import Effect.Class (class MonadEffect, liftEffect)
import Effect.Console (log)
import Effect.Exception (Error, error)
import Foreign (Foreign)
import Node.Express.App (App, get)
import Node.Express.Handler (Handler)
import Node.Express.Response (sendJson)
import Simple.JSON as JSON
import Network.AWS.Lambda.Express as Lambda


clientConfig :: ClientConfig
clientConfig =
{ host: "localhost"
, database: "test"
, port: 5432
, user: "testuser"
, password: "test"
, ssl: false
}

type IndexedTodo = { id :: Int, description :: String, isdone :: Boolean }

connectionInfo :: ConnectionInfo
connectionInfo = connectionInfoFromConfig clientConfig defaultPoolConfig

println :: forall a. MonadEffect a => String -> a Unit
println str = liftEffect $ log str

aPool :: Effect Pool
aPool = do
println "In Pooler"
mkPool connectionInfo

withConnectionPool :: forall a. Effect Pool -> (Client -> Aff a) -> Aff a
withConnectionPool somePool f = do
pool <- liftEffect somePool
withClient pool c -> f c

withConnection :: forall a. (Client -> Aff a) -> Aff a
withConnection = withConnectionPool aPool

read' :: forall a. JSON.ReadForeign a => Foreign -> Either Error a
read' = lmap (error <<< show) <<< JSON.read

readTodoList :: Aff (Array IndexedTodo)
readTodoList = do
let selectQuery = Query "select * from todos" :: Query IndexedTodo
withConnection $ query_ read' selectQuery

listTodosHandler :: Handler
listTodosHandler = do
userdata <- liftAff readTodoList
sendJson userdata


app :: App
app = do
get "/list" listTodosHandler

-- Define the AWS Lambda handler
handler :: Lambda.HttpHandler
handler = Lambda.makeHandler app









share|improve this question





























    1














    I would like to run PureScript code in AWS Lambda. Normally, if a lambda function has to call the database, the connection is stored in a global variable. Excuse me if the following JavaScript code is syntactically wrong as I don't write JavaScript but something like below is what I want(this is the code expected by AWS Lambda):



    function createConnection() {
    connection = SomeDBLibrary.createConnection(username, pwd)
    return connection;
    }
    global.db_connection = createConnection();

    handler = (event, context, callback) => {
    // TODO use global.db_connection here to call the database
    };

    module.exports {
    handler: handler
    };


    How do I write the equivalent PureScript to get such code? Currently, I call the createConnection() function in each of my CRUD methods which is wasteful.



    Edit 1:



    My actual PureScript code is below. The function which I want to call only once is aPool. However, I believe it's being called everytime one hits the /list endpoint. I would like it to be hit only once when the handler is loaded for the first time.



    module Main where

    import Prelude hiding (apply)

    import Data.Bifunctor (lmap)
    import Data.Either (Either)
    import Database.Postgres (Client, ClientConfig, ConnectionInfo, Pool, Query(Query), connectionInfoFromConfig, defaultPoolConfig, mkPool, query_, withClient)
    import Effect (Effect)
    import Effect.Aff (Aff)
    import Effect.Aff.Class (liftAff)
    import Effect.Class (class MonadEffect, liftEffect)
    import Effect.Console (log)
    import Effect.Exception (Error, error)
    import Foreign (Foreign)
    import Node.Express.App (App, get)
    import Node.Express.Handler (Handler)
    import Node.Express.Response (sendJson)
    import Simple.JSON as JSON
    import Network.AWS.Lambda.Express as Lambda


    clientConfig :: ClientConfig
    clientConfig =
    { host: "localhost"
    , database: "test"
    , port: 5432
    , user: "testuser"
    , password: "test"
    , ssl: false
    }

    type IndexedTodo = { id :: Int, description :: String, isdone :: Boolean }

    connectionInfo :: ConnectionInfo
    connectionInfo = connectionInfoFromConfig clientConfig defaultPoolConfig

    println :: forall a. MonadEffect a => String -> a Unit
    println str = liftEffect $ log str

    aPool :: Effect Pool
    aPool = do
    println "In Pooler"
    mkPool connectionInfo

    withConnectionPool :: forall a. Effect Pool -> (Client -> Aff a) -> Aff a
    withConnectionPool somePool f = do
    pool <- liftEffect somePool
    withClient pool c -> f c

    withConnection :: forall a. (Client -> Aff a) -> Aff a
    withConnection = withConnectionPool aPool

    read' :: forall a. JSON.ReadForeign a => Foreign -> Either Error a
    read' = lmap (error <<< show) <<< JSON.read

    readTodoList :: Aff (Array IndexedTodo)
    readTodoList = do
    let selectQuery = Query "select * from todos" :: Query IndexedTodo
    withConnection $ query_ read' selectQuery

    listTodosHandler :: Handler
    listTodosHandler = do
    userdata <- liftAff readTodoList
    sendJson userdata


    app :: App
    app = do
    get "/list" listTodosHandler

    -- Define the AWS Lambda handler
    handler :: Lambda.HttpHandler
    handler = Lambda.makeHandler app









    share|improve this question



























      1












      1








      1







      I would like to run PureScript code in AWS Lambda. Normally, if a lambda function has to call the database, the connection is stored in a global variable. Excuse me if the following JavaScript code is syntactically wrong as I don't write JavaScript but something like below is what I want(this is the code expected by AWS Lambda):



      function createConnection() {
      connection = SomeDBLibrary.createConnection(username, pwd)
      return connection;
      }
      global.db_connection = createConnection();

      handler = (event, context, callback) => {
      // TODO use global.db_connection here to call the database
      };

      module.exports {
      handler: handler
      };


      How do I write the equivalent PureScript to get such code? Currently, I call the createConnection() function in each of my CRUD methods which is wasteful.



      Edit 1:



      My actual PureScript code is below. The function which I want to call only once is aPool. However, I believe it's being called everytime one hits the /list endpoint. I would like it to be hit only once when the handler is loaded for the first time.



      module Main where

      import Prelude hiding (apply)

      import Data.Bifunctor (lmap)
      import Data.Either (Either)
      import Database.Postgres (Client, ClientConfig, ConnectionInfo, Pool, Query(Query), connectionInfoFromConfig, defaultPoolConfig, mkPool, query_, withClient)
      import Effect (Effect)
      import Effect.Aff (Aff)
      import Effect.Aff.Class (liftAff)
      import Effect.Class (class MonadEffect, liftEffect)
      import Effect.Console (log)
      import Effect.Exception (Error, error)
      import Foreign (Foreign)
      import Node.Express.App (App, get)
      import Node.Express.Handler (Handler)
      import Node.Express.Response (sendJson)
      import Simple.JSON as JSON
      import Network.AWS.Lambda.Express as Lambda


      clientConfig :: ClientConfig
      clientConfig =
      { host: "localhost"
      , database: "test"
      , port: 5432
      , user: "testuser"
      , password: "test"
      , ssl: false
      }

      type IndexedTodo = { id :: Int, description :: String, isdone :: Boolean }

      connectionInfo :: ConnectionInfo
      connectionInfo = connectionInfoFromConfig clientConfig defaultPoolConfig

      println :: forall a. MonadEffect a => String -> a Unit
      println str = liftEffect $ log str

      aPool :: Effect Pool
      aPool = do
      println "In Pooler"
      mkPool connectionInfo

      withConnectionPool :: forall a. Effect Pool -> (Client -> Aff a) -> Aff a
      withConnectionPool somePool f = do
      pool <- liftEffect somePool
      withClient pool c -> f c

      withConnection :: forall a. (Client -> Aff a) -> Aff a
      withConnection = withConnectionPool aPool

      read' :: forall a. JSON.ReadForeign a => Foreign -> Either Error a
      read' = lmap (error <<< show) <<< JSON.read

      readTodoList :: Aff (Array IndexedTodo)
      readTodoList = do
      let selectQuery = Query "select * from todos" :: Query IndexedTodo
      withConnection $ query_ read' selectQuery

      listTodosHandler :: Handler
      listTodosHandler = do
      userdata <- liftAff readTodoList
      sendJson userdata


      app :: App
      app = do
      get "/list" listTodosHandler

      -- Define the AWS Lambda handler
      handler :: Lambda.HttpHandler
      handler = Lambda.makeHandler app









      share|improve this question















      I would like to run PureScript code in AWS Lambda. Normally, if a lambda function has to call the database, the connection is stored in a global variable. Excuse me if the following JavaScript code is syntactically wrong as I don't write JavaScript but something like below is what I want(this is the code expected by AWS Lambda):



      function createConnection() {
      connection = SomeDBLibrary.createConnection(username, pwd)
      return connection;
      }
      global.db_connection = createConnection();

      handler = (event, context, callback) => {
      // TODO use global.db_connection here to call the database
      };

      module.exports {
      handler: handler
      };


      How do I write the equivalent PureScript to get such code? Currently, I call the createConnection() function in each of my CRUD methods which is wasteful.



      Edit 1:



      My actual PureScript code is below. The function which I want to call only once is aPool. However, I believe it's being called everytime one hits the /list endpoint. I would like it to be hit only once when the handler is loaded for the first time.



      module Main where

      import Prelude hiding (apply)

      import Data.Bifunctor (lmap)
      import Data.Either (Either)
      import Database.Postgres (Client, ClientConfig, ConnectionInfo, Pool, Query(Query), connectionInfoFromConfig, defaultPoolConfig, mkPool, query_, withClient)
      import Effect (Effect)
      import Effect.Aff (Aff)
      import Effect.Aff.Class (liftAff)
      import Effect.Class (class MonadEffect, liftEffect)
      import Effect.Console (log)
      import Effect.Exception (Error, error)
      import Foreign (Foreign)
      import Node.Express.App (App, get)
      import Node.Express.Handler (Handler)
      import Node.Express.Response (sendJson)
      import Simple.JSON as JSON
      import Network.AWS.Lambda.Express as Lambda


      clientConfig :: ClientConfig
      clientConfig =
      { host: "localhost"
      , database: "test"
      , port: 5432
      , user: "testuser"
      , password: "test"
      , ssl: false
      }

      type IndexedTodo = { id :: Int, description :: String, isdone :: Boolean }

      connectionInfo :: ConnectionInfo
      connectionInfo = connectionInfoFromConfig clientConfig defaultPoolConfig

      println :: forall a. MonadEffect a => String -> a Unit
      println str = liftEffect $ log str

      aPool :: Effect Pool
      aPool = do
      println "In Pooler"
      mkPool connectionInfo

      withConnectionPool :: forall a. Effect Pool -> (Client -> Aff a) -> Aff a
      withConnectionPool somePool f = do
      pool <- liftEffect somePool
      withClient pool c -> f c

      withConnection :: forall a. (Client -> Aff a) -> Aff a
      withConnection = withConnectionPool aPool

      read' :: forall a. JSON.ReadForeign a => Foreign -> Either Error a
      read' = lmap (error <<< show) <<< JSON.read

      readTodoList :: Aff (Array IndexedTodo)
      readTodoList = do
      let selectQuery = Query "select * from todos" :: Query IndexedTodo
      withConnection $ query_ read' selectQuery

      listTodosHandler :: Handler
      listTodosHandler = do
      userdata <- liftAff readTodoList
      sendJson userdata


      app :: App
      app = do
      get "/list" listTodosHandler

      -- Define the AWS Lambda handler
      handler :: Lambda.HttpHandler
      handler = Lambda.makeHandler app






      purescript






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 5 at 23:28

























      asked Nov 21 at 2:42









      RAbraham

      2,51222643




      2,51222643
























          1 Answer
          1






          active

          oldest

          votes


















          1














          I think that this requires a FFI like:



          foreign import dbConnection :: Effect Connection


          with implementation:



          exports.dbConnection = function() {
          if(globals.dbConnection === undefined) {
          globals.dbConnection = createConnection();
          }
          return globals.dbConnection;
          }





          share|improve this answer





















          • I realized something. The createConnection function is actually a purescript function. So I would call it in PureScript code and then hope to hold on to it as a global config, if that makes sense.
            – RAbraham
            Dec 3 at 23:41










          • I think createConnection should be rather an Effect Connection. Am I right?
            – paluh
            Dec 4 at 16:28










          • I have added my PureScript code. Does that clarify things a bit? Let me know if I can add more detail(or simplify it)
            – RAbraham
            Dec 5 at 23:29











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53404582%2fglobal-resources-in-purescriptfor-aws-lambda%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          I think that this requires a FFI like:



          foreign import dbConnection :: Effect Connection


          with implementation:



          exports.dbConnection = function() {
          if(globals.dbConnection === undefined) {
          globals.dbConnection = createConnection();
          }
          return globals.dbConnection;
          }





          share|improve this answer





















          • I realized something. The createConnection function is actually a purescript function. So I would call it in PureScript code and then hope to hold on to it as a global config, if that makes sense.
            – RAbraham
            Dec 3 at 23:41










          • I think createConnection should be rather an Effect Connection. Am I right?
            – paluh
            Dec 4 at 16:28










          • I have added my PureScript code. Does that clarify things a bit? Let me know if I can add more detail(or simplify it)
            – RAbraham
            Dec 5 at 23:29
















          1














          I think that this requires a FFI like:



          foreign import dbConnection :: Effect Connection


          with implementation:



          exports.dbConnection = function() {
          if(globals.dbConnection === undefined) {
          globals.dbConnection = createConnection();
          }
          return globals.dbConnection;
          }





          share|improve this answer





















          • I realized something. The createConnection function is actually a purescript function. So I would call it in PureScript code and then hope to hold on to it as a global config, if that makes sense.
            – RAbraham
            Dec 3 at 23:41










          • I think createConnection should be rather an Effect Connection. Am I right?
            – paluh
            Dec 4 at 16:28










          • I have added my PureScript code. Does that clarify things a bit? Let me know if I can add more detail(or simplify it)
            – RAbraham
            Dec 5 at 23:29














          1












          1








          1






          I think that this requires a FFI like:



          foreign import dbConnection :: Effect Connection


          with implementation:



          exports.dbConnection = function() {
          if(globals.dbConnection === undefined) {
          globals.dbConnection = createConnection();
          }
          return globals.dbConnection;
          }





          share|improve this answer












          I think that this requires a FFI like:



          foreign import dbConnection :: Effect Connection


          with implementation:



          exports.dbConnection = function() {
          if(globals.dbConnection === undefined) {
          globals.dbConnection = createConnection();
          }
          return globals.dbConnection;
          }






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 22 at 22:59









          paluh

          1,5611411




          1,5611411












          • I realized something. The createConnection function is actually a purescript function. So I would call it in PureScript code and then hope to hold on to it as a global config, if that makes sense.
            – RAbraham
            Dec 3 at 23:41










          • I think createConnection should be rather an Effect Connection. Am I right?
            – paluh
            Dec 4 at 16:28










          • I have added my PureScript code. Does that clarify things a bit? Let me know if I can add more detail(or simplify it)
            – RAbraham
            Dec 5 at 23:29


















          • I realized something. The createConnection function is actually a purescript function. So I would call it in PureScript code and then hope to hold on to it as a global config, if that makes sense.
            – RAbraham
            Dec 3 at 23:41










          • I think createConnection should be rather an Effect Connection. Am I right?
            – paluh
            Dec 4 at 16:28










          • I have added my PureScript code. Does that clarify things a bit? Let me know if I can add more detail(or simplify it)
            – RAbraham
            Dec 5 at 23:29
















          I realized something. The createConnection function is actually a purescript function. So I would call it in PureScript code and then hope to hold on to it as a global config, if that makes sense.
          – RAbraham
          Dec 3 at 23:41




          I realized something. The createConnection function is actually a purescript function. So I would call it in PureScript code and then hope to hold on to it as a global config, if that makes sense.
          – RAbraham
          Dec 3 at 23:41












          I think createConnection should be rather an Effect Connection. Am I right?
          – paluh
          Dec 4 at 16:28




          I think createConnection should be rather an Effect Connection. Am I right?
          – paluh
          Dec 4 at 16:28












          I have added my PureScript code. Does that clarify things a bit? Let me know if I can add more detail(or simplify it)
          – RAbraham
          Dec 5 at 23:29




          I have added my PureScript code. Does that clarify things a bit? Let me know if I can add more detail(or simplify it)
          – RAbraham
          Dec 5 at 23:29


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53404582%2fglobal-resources-in-purescriptfor-aws-lambda%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          404 Error Contact Form 7 ajax form submitting

          How to know if a Active Directory user can login interactively

          Refactoring coordinates for Minecraft Pi buildings written in Python