간단한 증명 증명 서번트 API를 설정하는 중에 문제가 있습니다.서번트가있는 데이터베이스 기반 REST API?
이data User = User { id :: Int, first_name :: String, last_name :: String } deriving (Eq, Show, Generic)
instance FromRow User
instance ToRow User
$(deriveJSON defaultOptions ''User)
type API = "users" :> ReqBody '[JSON] User :> Post '[JSON] User
이에 대한 핸들러 메소드는 다음과 같이 PostgreSQL을 - 간단한 사용 : 그런 된 DB 및 라우팅 방법에 연결하는 등의
create u = liftIO $ head <$> returning connection "insert into users (first_name, last_name) values (?,?) returning id" [(first_name u, last_name u)]
상용구 코드이 내 사용자의 데이터 형과 내 API 유형입니다 생략했다. 문제는 내가 POST 요청을 할 경우, 내가 새 사용자를 만드는 일을 할 무엇을 원하는, 그래서 나는 JSON 제공 할 것입니다 :
{ "first_name": "jeff", "last_name": "lebowski" }
하지만 내 프로그램
Error in $: When parsing the record User of type Lib.User the key id was not present.
와 런타임에 실패합니다
API가 ID 필드가있는 사용자를 지정했기 때문에 이는 의미가 있습니다. 그러나 요청에 bogus id를 넘겨주고 싶지는 않습니다. 왜냐하면 그 요청은 총체적이기 때문에 순차적으로 postgres에 할당되기 때문입니다. Postgres-simple은 다른 엔드 포인트에 GET 요청을 할 때 모델 데이터베이스 불일치로 인해 실패하기 때문에 User 필드에서 id 필드를 이동할 수 없습니다 (이는 id로 얻습니다. 위에 포함되지 않음).). 여기서 무엇을해야합니까? 사용자 정의 FromJson 인스턴스를 작성 하시겠습니까? Data.Aeson.TH 옵션에 omitNothingFields를 True로 설정하고 id 필드를 Maybe Int로 설정했지만 이미 작동하지 않았습니다. 조언을 주시면 감사하겠습니다.
개념이 조금 어둡습니다. 순수 하스켈 만 고려하십시오. 'mkUser :: User -> User'는 의미가 있습니까? 클라이언트가'User'를 만드는 데 필요한 정보만을 가진 메시지를 전달할 수 있도록 허용해야합니다. 예 :'CreateUser = CreateUser {givenName :: Text, surName :: Text}','type API = "users":> ReqBody '[JSON] CreateUser :>'JSON 사용자 '게시. –
필자는이를 고려해 봤지만 모든 엔드 포인트에 대해 추가 데이터 유형을 만들어야하는 것은 비 최적 솔루션이라고 생각합니다.나는 그것을 할 다른 방법이 있기를 바랬다. 이 실제로 구현하고 UserI (UserInput) 같은 패턴을 사용하여 자신을 발견했지만 이것은 하나의 필드 누락을 나타냅니다 및 입력 된 형식과 저장된 형식을 다른 나쁜 생각처럼 보입니다. 리팩토링 사용자가 UserI를 변경하는 것을 잊어 버리면 어떨까요? 하인이 피해야 할 부분이 아닌가? – asg0451
이 POST 요청은 사용자를 서버로 전달한 다음 저장합니다. Semantically 나는 그들을 같은 타입으로 유지하거나 UserI를 User로부터 컴파일 타임에 파생 시키길 원할 것이다. 내 개념이 어색하지 않고, 하스켈에서 경험이 없다. 유형이 의미하는 바를 의미한다는 것을 알았지 만 가장 단순한 API (사용자의 CRUD - 사용자)를 사용하여 개념 증명을 작성하여 서번트 사용을 정당화하려고 시도했습니다. 레일스에서 자동으로 처리됩니다. 그리고 그것이 얼마나 사소한 지에 놀랐습니다. – asg0451