---
# System prepended metadata

title: Habit engine interface

---

# Habit engine interface
- HTTP handler
    - Receives http requests and delegate the request to service for the response. Doesn't know much about the business logic
- Service 
    - Does buisness level logic like creating cohorts, inviting memebrs, sending welcome emails etc....
- Datastore
    - Used by the service to fetch and retrieve persistent data from sql DB


## Interfaces
```go=
// engine/datastore.go
// Datastore defines a set of functions to the persistent layer
// each function will accept a dstore interface which it will use
// to persist data. Reason we want to pass it explicitly is due to 
// the transactions on DB. User of datastore interface should pass this which would be Service
type CohortStore interface {
    // This will just create the cohort into db
    CreateCohort(dstore, cohort *engine.Cohort) (cohort, error)
    // fetch the cohort
    GetCohort(dstore, id string) (cohort, error)
}

// Datastore is the main interface embedding multiple small datastores
type DataStore interface{
    CohortStore
}

// engine/service.go
// Service defines a set of functions http or any other handler can use
type Service interface {
    // Creates a cohort, invote members, and send emails etc....
    CreateCohort(cohort *engine.Cohort) (cohort, error)
    // fetches cohorts and its sessions etc...
    GetCohort(id string) (cohort, error)
}

// service implements Service
type service struct{
    datastore engine.Datastore
}

func(s service)CreateCohort(cohort *engine.Cohort) (cohort, error){
    dstore := s.datastore.txn()
    within-txn{
        s.datstore.CreateCohort(dstore, cohort)
        s.datastore.SetCohortAdmins(dstore,cohort)
        s.sendEmails(cohort)
    }
}

// Handler functions are http handlers
type Handler struct{
    service engine.Service // interfce
}

// createcohort handler interacts with service to create cohort
func(h Handler) CreateCohort(w http.ResponseWriter, r *http.Request){
    cohort := cohortFrom(r)
    return h.service.CreateCohort(cohort)
}
```


## Testing
These defined interfaces above would be make it easy to write unit tests for each level i.e
- datastore tests will use postgres for testing
- service tests will use datastore default implementation with postgres to run tests
- HTTP tests would be done through API mocks