I'm dealing with design layers of an application. Basically what I've so far are:
- Business
- Architecture: Client-Server
- Techonologies: PHP+MySQL, HTML5, JS, 3rd parties APIs
My app
- Data Sources: MySql databases, 3rd party APIs
- Data Layer: Interface with CRUD operations, PDO for accessing DBs, Classes implementing CRUD interface, Classes for communication with APIs
- Repository: Classes & Interfaces with bussiness methods for accessing datasource.
- Business object: value objects and business rules
- Application layer: controls flow between Data Layer and Presentation.
- Presentation layer: html design with javascript & ajax & php code. Interacts with application layer for data retrieval
Implementation
Data Source
1x MySQL Database
1x 3rd party api
Data Layer
interface DSOps { /* * @return array */ function read($sql); /* * @return array */ function readAll($sql); /* * @return boolean */ function save($sql); /* * @return boolean */ function delete($sql); } use PDO; class DSSql implements DSOps { private $bd; public function __construct( PDO $bd) { $this->bd = $bd; } public function read($sql) { $stmt=$this->bd->prepare($sql); $stmt->execute(); $response = $stmt->fetch(PDO::FETCH_ASSOC); return $response; } public function readAll($sql) { $stmt=$this->bd->prepare($sql); $stmt->execute(); $response = $stmt->fetchAll(PDO::FETCH_ASSOC); return $response; } public function save($sql, $params) { $stmt=$this->bd->prepare($sql); return $stmt->execute($params); } public function borrar($sql, $params) { $stmt=$this->bd->prepare($sql); return $stmt->execute($params); } }
Repositories:
interface QueryClients { /* * @return Client */ public function searchById($id); /* * @return array() */ public function searchAll(); /* * @return int */ public function count(); } class RepoClients implements QueryClients { private $ds; public function __construct(DSOps $_ds) { $this->ds = $_ds; } /* * @return array */ public function searchById($id) { $sql = " SELECT * FROM clients WHERE id=$id;"; $response=$this->ds->read($sql); return $response; } /* * @return array() */ public function searchAll() { $sql = " SELECT * FROM clients; "; $response=$this->searchAll($sql); return $response; } .... }
I've multiple modules that implements the same design. When implementing these design I have the following doubts:
- Is correct to form queries at repository classes?
- Where should I handle SQL errors? Having an SQLError
- How should I handle access to APIs?
- As my app has role based access for users, how does this impacts my design/implementation? Based on logged user role I've create different classes using same interface but implementing different queries to database.