I'm trying to write simple rest API. I use Database.SQLite.Simple, Scotty and Aeson. I have a problem with DB query inside ScottyM() route function. When I have something like this
routes :: [User] -> ScottyM ()
routes allUsers = do
    get "/users/:id" $ do
        id <- param "id"
        json ([x | x <- allUsers, userId x == id] !! 0)
main = do
    conn <- open "data.db"
    users <- ( query_ conn "select id, first_name, second_name, team from users" :: IO [User] )
    scotty 3000 (routes users)
everything works fine, but in this scenario allUsers will get updated only once at server start. I want to query every time anyone ask about it. So I wrote this:
routes :: Connection -> ScottyM ()
routes conn= do
   get "/users/:id" $ do
        id <- param "id"
        users <- ( query_ conn "select id, first_name, second_name, team from users" :: IO [User] )
        json (users !! id)
main = do
    conn <- open "data.db"
    scotty 3000 (routes conn)
I get error
Couldn't match expected type ‘Web.Scotty.Internal.Types.ActionT
                                Text IO [a0]’
            with actual type ‘IO [User]’
In a stmt of a 'do' block:
  users <- (query_
              conn "select id, first_name, second_name, team from users" ::
              IO [User])
In the second argument of ‘($)’, namely
  ‘do { id <- param "id";
        users <- (query_
                    conn "select id, first_name, second_name, team from users" ::
                    IO [User]);
        json (users !! id) }’
In a stmt of a 'do' block:
  get "/users/:id"
  $ do { id <- param "id";
         users <- (query_
                     conn "select id, first_name, second_name, team from users" ::
                     IO [User]);
         json (users !! id) }
how to fix that? Also how can I pass arguments to sql query if I want for example select * from users where id = id from parameters?
 
                        
The
getfunction's second argument is of typeActionM. If you investigate further, you'll see this is just shorthand for the more complicated lookingActionT, witheasTextandmasIO.Because your
doblock is of this type, you can't callIOfunctions directly. You need to useliftIOto get the right type. So just adding aliftIObefore thequery_call should fix it.There's an example called using scotty with IO in the project wiki which shows this.