# 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