Skip to content

Core API Reference

API documentation for apigen-core module.

Base Entities

AuditableEntity

Base class for entities with audit fields.

java
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class AuditableEntity {

    @CreatedDate
    private LocalDateTime createdAt;

    @LastModifiedDate
    private LocalDateTime updatedAt;

    @CreatedBy
    private String createdBy;

    @LastModifiedBy
    private String modifiedBy;

    // Getters...
}

SoftDeletableEntity

Base class for entities with soft delete support.

java
@MappedSuperclass
public abstract class SoftDeletableEntity extends AuditableEntity {

    private LocalDateTime deletedAt;
    private String deletedBy;
    private boolean deleted = false;

    public void softDelete(String deletedBy) {
        this.deleted = true;
        this.deletedAt = LocalDateTime.now();
        this.deletedBy = deletedBy;
    }

    public void restore() {
        this.deleted = false;
        this.deletedAt = null;
        this.deletedBy = null;
    }
}

Services

CrudService

Generic CRUD service interface.

java
public interface CrudService<T, ID> {

    T create(T entity);

    Optional<T> findById(ID id);

    Page<T> findAll(Pageable pageable);

    Page<T> findAll(Specification<T> spec, Pageable pageable);

    T update(ID id, T entity);

    void delete(ID id);

    void softDelete(ID id);

    void restore(ID id);

    boolean exists(ID id);

    long count();
}

Usage

java
@Service
public class ProductServiceImpl
    extends AbstractCrudService<Product, Long>
    implements ProductService {

    public ProductServiceImpl(ProductRepository repository) {
        super(repository);
    }

    // Custom methods...
}

Controllers

CrudController

Base REST controller with automatic CRUD endpoints.

java
public abstract class CrudController<T, ID> {

    // GET /{id}
    @GetMapping("/{id}")
    public ResponseEntity<T> findById(@PathVariable ID id);

    // GET /
    @GetMapping
    public ResponseEntity<Page<T>> findAll(
        Pageable pageable,
        @RequestParam Map<String, String> filters
    );

    // POST /
    @PostMapping
    public ResponseEntity<T> create(@RequestBody @Valid T entity);

    // PUT /{id}
    @PutMapping("/{id}")
    public ResponseEntity<T> update(
        @PathVariable ID id,
        @RequestBody @Valid T entity
    );

    // DELETE /{id}
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> delete(@PathVariable ID id);

    // POST /{id}/restore
    @PostMapping("/{id}/restore")
    public ResponseEntity<T> restore(@PathVariable ID id);
}

Usage

java
@RestController
@RequestMapping("/api/products")
public class ProductController extends CrudController<Product, Long> {

    public ProductController(ProductService service) {
        super(service);
    }

    // All CRUD endpoints are inherited
    // Add custom endpoints as needed
}

Filtering

Filter Operators

OperatorDescriptionExample
eqEquals?name[eq]=iPhone
neNot equals?status[ne]=DELETED
likeContains (case-insensitive)?name[like]=phone
gtGreater than?price[gt]=100
gteGreater or equal?price[gte]=100
ltLess than?price[lt]=500
lteLess or equal?price[lte]=500
inIn list?status[in]=ACTIVE,PENDING
notInNot in list?status[notIn]=DELETED
betweenRange (inclusive)?price[between]=100,500
isNullIs null?description[isNull]=true
isNotNullIs not null?description[isNotNull]=true

SpecificationBuilder

Build JPA Specifications from filter parameters.

java
@Service
public class ProductService {

    public Page<Product> search(Map<String, String> filters, Pageable pageable) {
        Specification<Product> spec = SpecificationBuilder.build(filters);
        return repository.findAll(spec, pageable);
    }
}

Events

Domain Events

java
// Entity created
@EventListener
public void onCreated(EntityCreatedEvent<Product> event) {
    Product product = event.getEntity();
    // Handle creation...
}

// Entity updated
@EventListener
public void onUpdated(EntityUpdatedEvent<Product> event) {
    Product oldEntity = event.getOldEntity();
    Product newEntity = event.getNewEntity();
    // Handle update...
}

// Entity deleted
@EventListener
public void onDeleted(EntityDeletedEvent<Product> event) {
    Product product = event.getEntity();
    boolean isSoftDelete = event.isSoftDelete();
    // Handle deletion...
}

Caching

Cache Configuration

java
@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public CacheManager cacheManager() {
        CaffeineCacheManager manager = new CaffeineCacheManager();
        manager.setCaffeine(Caffeine.newBuilder()
            .maximumSize(1000)
            .expireAfterWrite(Duration.ofMinutes(10))
            .recordStats());
        return manager;
    }
}

Usage in Services

java
@Service
public class ProductServiceImpl implements ProductService {

    @Cacheable(value = "products", key = "#id")
    public Optional<Product> findById(Long id) {
        return repository.findById(id);
    }

    @CacheEvict(value = "products", key = "#id")
    public void delete(Long id) {
        repository.deleteById(id);
    }

    @CachePut(value = "products", key = "#result.id")
    public Product update(Long id, Product product) {
        // Update logic...
    }
}

Exception Handling

Standard Exceptions

java
// Not found
throw new EntityNotFoundException("Product", id);

// Validation error
throw new ValidationException("Price must be positive");

// Business rule violation
throw new BusinessException("Insufficient stock");

// Conflict (optimistic locking)
throw new ConflictException("Product was modified by another user");

Error Response (RFC 7807)

json
{
  "type": "https://api.example.com/errors/not-found",
  "title": "Entity Not Found",
  "status": 404,
  "detail": "Product with id 123 not found",
  "instance": "/api/products/123",
  "timestamp": "2024-01-15T10:30:00Z",
  "traceId": "abc123"
}

Released under the MIT License.