liveBook · Manning

Data layer

As explained in AI-Powered Developer: Build software with ChatGPT and Copilot

A data access layer is the part of an application responsible for communicating with data stores while isolating that communication from other application logic.

A data layer isolates communication with a database, file, API, cache, or other store from the application’s core behavior. Callers use a small interface instead of depending on storage details, so the backing technology can change without reshaping every caller. section 4.3.3

A Repository can serve as the data layer’s boundary. Define a generic contract for create, read, update, delete, and listing operations; then provide implementations for particular entity types and stores. An application service delegates persistence work to the repository rather than manipulating storage directly. section 4.3.3

Listing 4.26 Code for BaseRepository, our generic data access layer
from abc import ABC, abstractmethod
from typing import List, TypeVar, Generic
  
T = TypeVar('T')
  
class BaseRepository(ABC, Generic[T]):
    @abstractmethod
    def create(self, entity: T) -> None:
        pass
  
    @abstractmethod
    def read(self, entity_id: int) -> T:
        pass
  
    @abstractmethod
    def update(self, entity: T) -> None:
        pass
  
    @abstractmethod
    def delete(self, entity_id: int) -> None:
        pass
  
    @abstractmethod
    def get_entities(self) -> List[T]:
        pass

This generic repository contract makes the data-layer boundary concrete: callers work with typed CRUD methods while implementations supply storage-specific behavior. section 4.3.3

Swap an in-memory store for persistent storage

An AssetManager can work through an InMemoryAssetRepository backed by a list, enabling an end-to-end CRUD test. The same repository boundary can later conceal a PostgreSQL-backed implementation. For ORM persistence, keep metadata-bearing ORM models outside the domain model and map them before objects return to the core. section 4.3.3 section 5.1

Keep the boundary useful by separating these responsibilities:

  • Expose application-facing CRUD operations through a repository contract. section 4.3.3
  • Implement the contract for each storage mechanism, such as an in-memory list or PostgreSQL-backed persistence. section 4.3.3 section 5.1
  • Map persistence models to domain models when ORM metadata would otherwise leak into business objects. section 5.1

How AI-Powered Developer: Build software with ChatGPT and Copilot covers it

How deep it goes
Defines generic typed CRUD contracts, in-memory implementation, and ORM-to-domain mapping without showing a persistent repository implementation.
Examples
Demonstrates BaseRepository, InMemoryAssetRepository, AssetManager delegation, and SQLAlchemy-style AssetModel and FundingDetailsModel classes.
What it assumes
Assumes familiarity with application models and CRUD while introducing repository contracts and ORM-model separation.
What you can do after
Build it from scratch as a typed repository boundary with replaceable in-memory and persistent storage implementations.
How it connects
Connects the Repository Pattern, CRUD operations, ports and adapters, ORM, and domain models.

Also explained in

Compare how 6 books explain data layer →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of AI-Powered Developer: Build software with ChatGPT and Copilot. The section links point to the parts of the book it draws on.