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
get
function's second argument is of typeActionM
. If you investigate further, you'll see this is just shorthand for the more complicated lookingActionT
, withe
asText
andm
asIO
.Because your
do
block is of this type, you can't callIO
functions directly. You need to useliftIO
to get the right type. So just adding aliftIO
before thequery_
call should fix it.There's an example called using scotty with IO in the project wiki which shows this.