yesodweb / yesodweb/persistent

`HasPersistBackend` should be more deeply integrated

Open
#955 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Haskell
Stars
486
Forks
306
PR merge metrics
No merged PRs in 30d

Description

I currently need to put more than just a SqlBackend in the ReaderT that gets passed around throughout the app.

I saw "HasPersistBackend" and the associated documentation and assumed that would cover my use-case perfectly. It seemed to mimic the commonly seen "has pattern" that allows for scalabe and composable usage of ReaderT.

However I was disappointed to learn that a lot of the classes operate directly on backend instead of on BaseBackend backend, and thus to actually use my new data Environment = ... SqlBackend ... type I needed to write quite a lot of very trivial boilerplate code.

It seems to me as though constraints of various functions should depend on BaseBackend backend so that you only need to define HasPersistBackend to make a custom environment work.

If the purpose of BaseBackend is a little different from what I am envisioning, and the requirement to define these trivial class instances is for customizing permissions, then perhaps a second class is needed:

class HasPersistBackend env where
    type PersistBackend env :: Type
    persistBackend :: env -> PersistBackend env

class HasBaseBackend backend where
    type BaseBackend backend :: Type
    baseBackend :: backend -> BaseBackend backend

And in my use case I would define:

instance HasPersistBackend AppEnv where
    type PersistBackend AppEnv = SqlBackend
    persistBackend appEnv = appEnvBackend appEnv

And I will not have to change any of my existing code besides generalizing some overly monomorphic code (that in hindsight I should have generalized to HasPersistBackend env => from the start).

Currently I seem to be in a pretty awkward place of either defining a large amount of boilerplate for my AppEnv type, or having to modify the ReaderT env whenever I call into a db function.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing HasPersistBackend, BaseBackend, ReaderT usage, and the associated documentation, then trace the classes and functions that currently require backend directly. Compare the proposed abstractions and determine how a custom AppEnv containing SqlBackend can be used without repetitive instances or changing the ReaderT environment. Done means the integration approach is documented and covered by relevant tests or examples.

Written by the indexing model from the issue text.

Assessment

Tech stack
haskell
Domain
backend, databases
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.