Idiomatic Haskell is in doing as much static checking as possible. You should always approach your problem from a perspective of whether it is possible to replace dynamic checks with static ones. That's essentially what makes the following statement about Haskell quite close to reality: "If it compiles, it works". So definitely a "No" to working with plain JSON.
Your solution with FullUser
and PartialUser
is correct. Although I would suggest to take a different naming approach: User
and UserJSON
- this way you get a quite descriptive and reasonable meaning.
There is however a small problem with Aeson: the generated instances don't yet support parsing missing fields (please, vote on the issue). So you'll have to define the instances manually.