2016-12-28 8 views
0

간단한 휴식 API를 쓰려고합니다. Database.SQLite.Simple, Scotty 및 Aeson을 사용합니다. ScottyM() 라우트 기능 내에서 DB 쿼리에 문제가 있습니다. 내가 이런 식으로 할 때Haskell 데이터베이스 쿼리 ScottyM() 함수 내

routes :: [User] -> ScottyM() 
routes allUsers = do 
    get "https://stackoverflow.com/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) 

모든 것이 잘 작동하지만,이 시나리오에서는 모든 사용자가 서버 시작시 한 번만 업데이트됩니다. 누구나 질문 할 때마다 질문하고 싶습니다. 오류가

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 "https://stackoverflow.com/users/:id" 
    $ do { id <- param "id"; 
     users <- (query_ 
        conn "select id, first_name, second_name, team from users" :: 
        IO [User]); 
     json (users !! id) } 

어떻게 문제를 해결하기 위해

routes :: Connection -> ScottyM() 
routes conn= do 
    get "https://stackoverflow.com/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) 

내가 얻을 : 그래서 내가 쓴? 또한 예를 들어 싶다면 SQL 쿼리에 인수를 전달할 수 있습니까? select * from users where id = id from parameters?

답변

3

get 함수의 두 번째 인수는 ActionM입니다. 더 자세히 살펴보면 ActionT, eText, mIO 인 복잡한보기의 단순한 축약임을 알 수 있습니다.

do 블록이이 유형이므로 IO 함수를 직접 호출 할 수 없습니다. 올바른 유형을 얻으려면 liftIO을 사용해야합니다. 따라서 query_ 호출 전에 liftIO을 추가하면 해결됩니다.

프로젝트 위키에 using scotty with IO이라는 예가 있습니다.