mevdschee / php-crud-api

Single file PHP script that adds a REST API to a SQL database

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Using Customization handler to insert app-generated ID

apps-caraga opened this issue · comments

I was just trying to use Universally Unique Lexicographically Sortable Identifier ULID with this library and was able to insert the ULID via the multitenancy middleware as follows:

	'multiTenancy.handler' => function ($operation, $tableName) {
			if($operation =='create' && $tableName=='data'){ 
				return['id'=>Ulid::generate()];
			}
		},

With SQLite, the post request is ok (data is saved and response status is HTTP 200) but returns {} or an empty array. Any idea why?

SQLite table schema:

CREATE TABLE data (
    id        TEXT (26) PRIMARY KEY
                        NOT NULL,
    content      TEXT,
    createdAt DATETIME  NOT NULL
                        DEFAULT (strftime('%Y-%m-%d %H:%M:%fZ') ) 
);

With SQLite, the post request is ok (data is saved and response status is HTTP 200) but returns {} or an empty array. Any idea why?

I think it is because the code returns the insert(ed) id and not the primary key.

So it doesn't matter if the inserted ULID is the primary key. Anyway, is multitenancy the correct way to do this or is there a better way? (aside from client-side ID generation) 😁
I also tried using customization.beforeHandler and it got the same result

So i got it to return the new ULID by adding it in the afterHandler.

	'customization.beforeHandler' => function ($operation, $tableName, $request, $environment) {
			if($operation =='create' && $tableName =='data'){
				$body = $request->getParsedBody();
				$body->id = $environment->ulid = Ulid::generate();
				return $request->withParsedBody($body);
			}
		},
		'customization.afterHandler' => function ($operation, $tableName, $response, $environment) {
			if($operation =='create' && $tableName =='data'){
				return ResponseFactory::from(200, 'text/plain',$environment->ulid);
			}
		},	

It's not very good-looking code but it kinda works for my use case. (Although I'm not sure if this is a correct way to use the $environment variable.)😁

Excellent, that is exactly how that I envisioned that it would be used! Keep it up..

Just noting here that the before/afterHandler does not work with user registration even though it's a POST request.

@apps-caraga I would say that depends on the order of the middlewares.

depends on the order of the middlewares.

But it seems that no matter how I order the middlewares, the ULID is not inserted via the customization beforeHandler during dbAuth registration request.

Did you load the Customization handler before DbAuth? You test for 'create' operation, while the DbAuth uses the 'unknown' if I read the code correctly. Did you debug the code? You should be able to do something when calling Customization before DbAuth.

You should be able to do something when calling Customization before DbAuth.

I was able to retrieve the path segment thru RequestUtils::getPathSegment($request, 1); parameters so I can check if the current path or operation is 'login','register', or 'logout' operation instead of just checking if the operation is 'unknown'. Then I was able to add the new ID to the $body.

'customization.beforeHandler' => function ($operation, $tableName, $request, $environment) {
			$body = $request->getParsedBody();
			$path = RequestUtils::getPathSegment($request, 1);
			if($path === 'register'  ){
				$body->id = $environment->ulid =   Ulid::generate()->__toString();
				$environment->currPath = $path;
				return $request->withParsedBody($body);
			}
		},

The problem is the dbAuth register processes only the $username and $password so the custom ID added to the body is ignored (line 60-61 of DbAuth middleware ) 😉
image

I think it cannot be done without modifying the dbAuth middleware

Yup,that's the case.But it may not be a very common use case as of now. For now, I'll just copy some code in the register endpoint and insert it in my beforeHandler as a temp. workaround😁

For future, this feature might good to be implemented in an enhanced dbAuth middleware that can accept extra registration data.