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.