# How to Insert a validation before DB INSERT (SLIM4 API SKELETON)

**URL:** <https://discourse.slimframework.com/t/how-to-insert-a-validation-before-db-insert-slim4-api-skeleton/5424>\
**Category:** Questions\
**Created:** [November 5, 2022, 10:27am UTC](https://discourse.slimframework.com/t/how-to-insert-a-validation-before-db-insert-slim4-api-skeleton/5424 "2022-11-05T10:27:50Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![cws101](https://avatars.discourse-cdn.com/v4/letter/c/958977/32.png) [@cws101](https://discourse.slimframework.com/u/cws101)\
**Post date:** [November 5, 2022, 10:27am UTC](https://discourse.slimframework.com/t/how-to-insert-a-validation-before-db-insert-slim4-api-skeleton/5424/1 "2022-11-05T10:27:50Z")

</div>

I’m working with [SLIM4 API SKELETON](https://github.com/maurobonfietti/slim4-api-skeleton) by Mauro Bonfietti.

From my little experience, I was able to run the app and include CRUDs for my tables. Now to mold the app to my needs.

There are the Sevice and Repository phps for each table. I would like to add a CONDITION before a create/insert is done.

As an example, I have a visits table. It has visitor\_id and datetime of visit. every time this visitor visits, the app inserts the visitor\_id and the datetime of visit. As for the condition, let us say, the app only insert a record if the visitor’s last visit is more than 10mins older than the current visit.

---

<div class="post-metadata">

**Author:** ![tj\_gumis](https://avatars.discourse-cdn.com/v4/letter/t/c89c15/32.png) [@tj\_gumis](https://discourse.slimframework.com/u/tj_gumis)\
**Post date:** [November 5, 2022, 11:16am UTC](https://discourse.slimframework.com/t/how-to-insert-a-validation-before-db-insert-slim4-api-skeleton/5424/2 "2022-11-05T11:16:00Z")

</div>

You just need to fetch your `visits` table by your `visitor_id` before, and in case if the result is not empty compare `datetime` registered with the current one. Afterwards, depending on the result you process insert/update or not.

---

<div class="post-metadata">

**Author:** ![cws101](https://avatars.discourse-cdn.com/v4/letter/c/958977/32.png) [@cws101](https://discourse.slimframework.com/u/cws101)\
**Post date:** [November 5, 2022, 3:28pm UTC](https://discourse.slimframework.com/t/how-to-insert-a-validation-before-db-insert-slim4-api-skeleton/5424/3 "2022-11-05T15:28:52Z")

</div>

Thanks for the reply, what I’m looking for though is ‘where/how’ to code.

Do I create a function that checks for the condition within the **visitsservice** or **visitsrepository**. After checking with the condition, how do I code if the condition checks and at the same time if it doesn’t satisfy the condition.

Also, there is a directory for visits inside **Controller** directory, too.

---

<div class="post-metadata">

**Author:** ![tj\_gumis](https://avatars.discourse-cdn.com/v4/letter/t/c89c15/32.png) [@tj\_gumis](https://discourse.slimframework.com/u/tj_gumis)\
**Post date:** [November 5, 2022, 11:20pm UTC](https://discourse.slimframework.com/t/how-to-insert-a-validation-before-db-insert-slim4-api-skeleton/5424/4 "2022-11-05T23:20:38Z")

</div>

Lets start with the basics - basic CRUD flow code structure:

1. First option:

- 4 routes - CREATE visit, READ visit, UPDATE visit, DELETE visit
- 1 controller - VisitController
  - with VisitService injected into contstructor
  - with 4 actions(methods) create, get, update, delete calling related VisitService methods

- 1 service - VisitService
  - with injected VisitRepository
  - with 4 methods create, get, update, delete

1. Second option:

- 4 routes - CREATE visit, READ visit, UPDATE visit, DELETE visit
- 4 action controllers - CreateVisitActionController, etc.
  - each one with VisitService injected into contstructor
  - each one with single \_\_invoke method calling related VisitService method

- 1 service - VisitService
  - with injected VisitRepository
  - with 4 methods create, get, update, delete

1. Third option:

- 4 routes - CREATE visit, READ visit, UPDATE visit, DELETE visit
- 4 action controllers - CreateVisitActionController, etc.
  - each one with its proper ActionService injected into constructor or as a parameter of \_\_invoke method
  - each one with single \_\_invoke method calling related VisitActionService by its \_\_ivoke method

- 4 action services - CreateVisitActionService, etc.
  - each one with injected VisitRepository
  - each one with with single \_\_invoke method

1. My favorite option:

- 4 routes - CREATE visit, READ visit, UPDATE visit, DELETE visit
- 1 controller - VisitController
  - with 4 actions(methods) create, get, update, delete
  - with 4 VisitActionServices injected as parameter into proper controller’s action(method) - CreateVisitActionService, etc…

- 4 action services - CreateVisitActionService, etc.
  - each one with injected VisitRepository into constructor
  - each one with with single \_\_invoke method

No matter which option you select, your issue is related to `create/add` process, so alternatively:

- in your `VisitService` `create()` method or
- in your `CreateVisitActionService` `__invoke` method you are supposed to call your `VisitRepository` two times depending on the situation:
  - `$this->visitRepository->getById($id)`
  - check required condition
  - and (or not) `$this->visitRepository->create($visit)`

---

<div class="post-metadata">

**Author:** ![cws101](https://avatars.discourse-cdn.com/v4/letter/c/958977/32.png) [@cws101](https://discourse.slimframework.com/u/cws101)\
**Post date:** [November 22, 2022, 10:47am UTC](https://discourse.slimframework.com/t/how-to-insert-a-validation-before-db-insert-slim4-api-skeleton/5424/5 "2022-11-22T10:47:19Z")

</div>

Just a follow, is this true if I also want to add additional information to the result.

For example, I GET an array filled with visit count by category/type. Then I want to add percentage per category/type of visit.

---

<div class="post-metadata">

**Author:** ![tj\_gumis](https://avatars.discourse-cdn.com/v4/letter/t/c89c15/32.png) [@tj\_gumis](https://discourse.slimframework.com/u/tj_gumis)\
**Post date:** [November 22, 2022, 4:32pm UTC](https://discourse.slimframework.com/t/how-to-insert-a-validation-before-db-insert-slim4-api-skeleton/5424/6 "2022-11-22T16:32:47Z")

</div>

Regardless of an approach, it is important to leave CRUD’s `actionService` or `service`’s methods (I mean those which are able to query database) as generic as possible.  
You can query `count` but correct me if I am wrong with `percent` it is not that obvious.  
If you need any additional operations (transformations, calculations) do it by an additional service having appropriate method that accepts generic results of the first one as a parameter and returns them as you need:

Controller’s action example without additional transformations:

```php
    public function getCategoriesCount(
        Request $request,
        Response $response,
        GetCategoriesCountAction $action
    ): Response {
        return ($this->responder)(
            $response,
            $action($request)
        );
    }

```

Controller’s action example with additional transformations:

```php
    public function getCategoriesPercentage(
        Request $request,
        Response $response,
        GetCategoriesCountAction $action,
        TransformationService $service
    ): Response {
        $result = $action($request);
        return ($this->responder)(
            $response,
            $service->transformCountIntoPercentage($result)
        );
    }

```

---

<div class="post-metadata">

**Author:** ![cws101](https://avatars.discourse-cdn.com/v4/letter/c/958977/32.png) [@cws101](https://discourse.slimframework.com/u/cws101)\
**Post date:** [December 1, 2022, 8:02am UTC](https://discourse.slimframework.com/t/how-to-insert-a-validation-before-db-insert-slim4-api-skeleton/5424/7 "2022-12-01T08:02:02Z")

</div>

Hello,

I’m not sure how to code this. Here is my file organization:

```auto
Contoller folder
--Visits folder
  --Base.php
  --GetCount.php
      final class GetCount extends Base {
        public function __invoke(Request $request, Response $response): Response
          getVisitsService()->getCount($input);
      }

Repository folder
--VisitsRepository.php
  final class VisitsRepository {
    public function getCount(object $visits): array {
      // database query here.
    }
  }

Service folder
--VisitsService.php
  final class VisitsService {
    public function getCount(array $input): array {
      return $this->visitsRepository->getCount($visits);
    }
  }

```

Forgive me if I’m very slow at this. I believe my CRUD follows Second option. My question is: where do I place the functions **getCategoriesCount** and **getCategoriesPercentage**?

---

<div class="post-metadata">

**Author:** ![tj\_gumis](https://avatars.discourse-cdn.com/v4/letter/t/c89c15/32.png) [@tj\_gumis](https://discourse.slimframework.com/u/tj_gumis)\
**Post date:** [December 2, 2022, 7:24pm UTC](https://discourse.slimframework.com/t/how-to-insert-a-validation-before-db-insert-slim4-api-skeleton/5424/8 "2022-12-02T19:24:27Z")

</div>

> My question is: where do I place the functions **getCategoriesCount** and **getCategoriesPercentage**?

It depends.

You do not present any details about your application schema, so for a simple case scenario we are dealing with two separate scopes - `Visit` and `Category`. So everything related to `Visit` stays within `Visits` folder, and what is related to `Category` stays within `Categories` folder.  
So, your `count` and `percentage` appears to be 5 th and 6 th after 4 actions related to your basic CRUD. However …  
If you intend to `count` or get `percentage` of `Category` being in relation with some `Visit` you have to consider a necessity of a third scope `VisitCategory`, within a separate folder and with separate set of classes (controller, actions, repositories, etc …) responsible for all requests related to a relation `VisitCategory` as a whole.

---

<div class="post-metadata">

**Author:** ![cws101](https://avatars.discourse-cdn.com/v4/letter/c/958977/32.png) [@cws101](https://discourse.slimframework.com/u/cws101)\
**Post date:** [December 5, 2022, 7:52am UTC](https://discourse.slimframework.com/t/how-to-insert-a-validation-before-db-insert-slim4-api-skeleton/5424/9 "2022-12-05T07:52:34Z")

</div>

Does the application schema means my database and the tables and fields I’m working on? Currently it’s like this:

1. Visits table (id, visitor\_id, created\_at, updated\_at)
2. Visitors table (id, visitor\_id, name, grade, section, teacher, type, created\_at, updated\_at)

Looking into this, I think, I may need to modify my visitors table a little more to accommodate some more situations. Like: school year.

1. Batch table (id, visitor\_id, school\_year, grade, section, teacher, created\_at, updated\_at)
2. new Visitors table (id, visitor\_id, name, type, created\_at, updated\_at)

The count and percentage per category is say per grade. So I’m going to name the scope `VisitsGrade` and then create the necessary folders and classes. Is this okay? Also for this, I’m just going to do queries that involve more than 1 table.

---

<div class="post-metadata">

**Author:** ![tj\_gumis](https://avatars.discourse-cdn.com/v4/letter/t/c89c15/32.png) [@tj\_gumis](https://discourse.slimframework.com/u/tj_gumis)\
**Post date:** [December 5, 2022, 10:59am UTC](https://discourse.slimframework.com/t/how-to-insert-a-validation-before-db-insert-slim4-api-skeleton/5424/10 "2022-12-05T10:59:46Z")

</div>

`Visits` table - What kind of visits? `many-to-many` meaning sort of museum trips related to a group of visitors (students,workers,tourists) or `one-to-one` meaning some single person consultations with a doctor?

`Visitors` table - I don’t think this table is necessary. Regardless of kind of a visitor (student, worker, teacher, tourist) your `visitor_id` may be easily related to any external `id` in `Students` or `Workers` or `Teachers` etc tables and it is wrong to repeat already existing information.

`NewVisitors` table - what do you need it for?

#### For `one-to-one` I’d rather create:

`Visits` table (id, ref, visitor\_id, created\_at, updated\_at)  
`Students` table (id, name, grade\_id, section\_id, teacher\_id, created\_at, updated\_at)  
`Teachers` table (id, name, created\_at, updated\_at)  
`Grade` table (id, ref)  
`Section` table (id, ref)

```sql
SELECT *
FROM visits 
LEFT JOIN students ON visits.visitor_id = students.id
    LEFT JOIN grades ON students.grade_id = grades.id
    LEFT JOIN sections ON students.section_id = sections.id
    LEFT JOIN teachers ON students.teacher_id = tearchers.id
WHERE students.grade_id = 'A'

```

where `grades` and `sections` are simple tables representing list of references.

This way you have 5 scopes represented by folders `Visits`, `Students`, `Grades`, `Sections`, `Teachers`.  
There is no need to create an additional `VisitsGrades` scope, because your field `grade` is already within the scope of `Visit` by referenced `student_id`.

#### For the case of `many-to-many` situation changes:

Now you need the third scope, `VisitsStudents`:

- `VisitsStudents` table (id, visit\_id, student\_id)

with slight modification of joined tables:

- `Visits` table (id, ref, created\_at, updated\_at)
- `Students` table (id, name, grade\_id, section\_id, teacher\_id, created\_at, updated\_at)

```sql
SELECT *
FROM visits_students 
LEFT JOIN visits ON visits_students.visit_id = visits.id
LEFT JOIN students ON visits_students.student_id = students.id
    LEFT JOIN grades ON students.grade_id = grades.id
    LEFT JOIN sections ON students.section_id = sections.id
    LEFT JOIN teachers ON students.teacher_id = teachers.id
WHERE students.grade_id = 'A'  

```

> As you can see there is lots of `JOIN` s in sql queries, so this is a case where it is wise to use prefixes to avoid table fields names conflicts, for example: `id` → `std_id`.

---

<div class="post-metadata">

**Author:** ![cws101](https://avatars.discourse-cdn.com/v4/letter/c/958977/32.png) [@cws101](https://discourse.slimframework.com/u/cws101)\
**Post date:** [December 12, 2022, 7:28am UTC](https://discourse.slimframework.com/t/how-to-insert-a-validation-before-db-insert-slim4-api-skeleton/5424/11 "2022-12-12T07:28:03Z")

</div>

> [@tj\_gumis](#):
>
> `Visits` table - What kind of visits?

Yes, meaning how often a student/teacher visit the museum or the library and such.

> [@tj\_gumis](#):
>
> `NewVisitors` table - what do you need it for?

It’s the newly modified version of Visitors table.

> [@tj\_gumis](#):
>
> #### For `one-to-one` I’d rather create:
> 
> `Visits` table (id, ref, visitor\_id, created\_at, updated\_at)  
> `Students` table (id, name, grade\_id, section\_id, teacher\_id, created\_at, updated\_at)  
> `Teachers` table (id, name, created\_at, updated\_at)  
> `Grade` table (id, ref)  
> `Section` table (id, ref)

Yes, I believe I’ll be creating the db this way. I would also like to point out the Batch table (for me it means managing the school year. Students will attend the same school every year and will have different grade level.

Always appreciated this discussion. Thanks, @tj_gumis .
