Jump to content

New Module: AppApi


Sebi

Recommended Posts

Hi @Sebi

thanks for your reply. I've thought about it again. The website where I'm working on will be fully headless. The URLs mappings are then handled by a vuejs frontend. So in this case it does not matter much if it's controlled by a var or URL segement (Forgot about this when asking :roll_eyes:).

The requirements of the site are still a bit unclear but it looks I do not need the c-u-d of C-R-U-D. This is why I most likely will just build a small API with the new URL Hooks. This is how I would handle the language there (Quick and dirty example):

        $this->wire()->addHook('/{lang}/api/books', function($event) {
            $books = $this->pages->find("template=books");
            $response_arr = [];          
            foreach ($books as $book){
                $current_page = [];
                $current_page['title'] = $book->getLanguageValue($event->lang, 'title');
                $current_page['author'] = $book->getLanguageValue($event->lang, 'author');
				// ...
                array_push($res, $current_page);
            }
        	header('Content-Type: application/json; charset=utf-8');
        	echo json_encode( $response_arr );
        });

But it's great to have your Extension available in case there is some "heavier" API to build ;))

@Jukka Nice to hear!!

Link to comment
Share on other sites

Posted (edited)

@Sebi

Thanks for this great module, I'm testing it for a project right now. 

However I'm running into a slight problem, not sure if this is a bug or it's something on my end.
I'm testing it on two PW 3.0.165 instances and in one of them everything works perfect.

In the other I can't seem to edit an application to set an apiKey in the admin. When clicking it (/processwire/setup/appapi/application/edit/1) it renders the 404 of the website instead of showing the edit page of the application. I have two languages setup for this project and also formBuilder module. Other than that, I don't see any differences with the other working project.

The applications overview (/processwire/setup/appapi/applications) does work the way it should.

Do you have any idea where this could be going wrong?

 

Update: I removed all modules from the failing project that I had installed (FormBuilder, Language support), but to no avail.
I can navigate to /processwire/setup/appapi/applications/ which lists all applications, and /processwire/setup/appapi/application/edit (without an ID and it will give me a missing ID message within the admin). As soon as I add an ID (/processwire/setup/appapi/application/edit/1) it will fail, throws a 404 outside of the admin.

I also cleared out my ready.php to prevent any hooks causing issues.

 

@ryan You obviously can't provide support for a custom module, but is there anything here that sounds familiar? Could there be a routing or permission issue here? Is there some caching going on somewhere that might be causing this?

Edited by PascalKonings
Link to comment
Share on other sites

On 5/10/2022 at 12:46 PM, PascalKonings said:

@Sebi

Thanks for this great module, I'm testing it for a project right now. 

However I'm running into a slight problem, not sure if this is a bug or it's something on my end.
I'm testing it on two PW 3.0.165 instances and in one of them everything works perfect.

In the other I can't seem to edit an application to set an apiKey in the admin. When clicking it (/processwire/setup/appapi/application/edit/1) it renders the 404 of the website instead of showing the edit page of the application. I have two languages setup for this project and also formBuilder module. Other than that, I don't see any differences with the other working project.

The applications overview (/processwire/setup/appapi/applications) does work the way it should.

Do you have any idea where this could be going wrong?

 

Update: I removed all modules from the failing project that I had installed (FormBuilder, Language support), but to no avail.
I can navigate to /processwire/setup/appapi/applications/ which lists all applications, and /processwire/setup/appapi/application/edit (without an ID and it will give me a missing ID message within the admin). As soon as I add an ID (/processwire/setup/appapi/application/edit/1) it will fail, throws a 404 outside of the admin.

I also cleared out my ready.php to prevent any hooks causing issues.

 

@ryan You obviously can't provide support for a custom module, but is there anything here that sounds familiar? Could there be a routing or permission issue here? Is there some caching going on somewhere that might be causing this?

@ryan @Sebi Found it! I had maxUrlSegments set to 2 in my config file #doh

  • Like 1
Link to comment
Share on other sites

@Sebi

I'm running into a problem deleting a repeater item through the API, or any page for that matter.

Using my code below I'm getting an error

public static function deleteEvent($data) {
  $data = AppApiHelper::checkAndSanitizeRequiredParameters($data, ['id|int']);

  // $data->id returns an integer
  wire('pages')->get($data->id)->delete();

  // Using a static ID also fails
  // wire('pages')->get(1066)->delete();

  return [
  'message' => 'deletion successful',
  'status' => 200
  ];
}

 

The error I'm getting is:

devmessage: {message: "Trying to get property 'id' of non-object", location: '/myDev/wire/core/PagesEditor.php', line: 296}
error: "Internal Server Error"

 

This line is within the isDeleteable function, where it tries to get the ID of the page that needs to be deleted, however it seems the $page:

else if($page->id === $this->wire('page')->id && $this->wire('config')->installedAfter('2019-04-04')) {
	$error = "it is the current page being viewed, try \$pages->trash() instead";
}

 

I've set up the route without any auth or roles, so it should work from that perspective. Other routes getting and posting are working fine! And running the API from the template directly works perfectly: 

wire('pages')->get(1066)->delete();

 

Am I missing something here?

Link to comment
Share on other sites

  • 2 weeks later...
On 5/16/2022 at 9:44 AM, PascalKonings said:

@Sebi

I'm running into a problem deleting a repeater item through the API, or any page for that matter.

Am I missing something here?

@Sebi Any chance you have time to take a look at my issue above?

Link to comment
Share on other sites

This error is related to Processwire, not to the module. Check the documentation for the Repeater field in the section "Using the API to add or remove repeater items":  https://processwire.com/docs/fields/repeaters/ You can also check this post that talks about the same problem: https://processwire.com/talk/topic/16276-remove-repeater-item-by-page-id-rather-than-item-id/

 

  • Like 2
Link to comment
Share on other sites

Because I'm using the LoginRegisterPro module, users use their email to log in. So I'm wondering, for authentication, should i make an endpoint that returns the username for a given email address and use that to authenticate or is there a better way to solve this that doesn't use an extra request.

Link to comment
Share on other sites

  • 1 month later...

Great module, @Sebi! As it is out there for almost 2 years now, maybe someone found an elegant solution for caching the generated output (and rebuilding that cache if a page or child page is updated)?

I have seen @toni´s approach and could build something on top of that for my specific use case, but I guess there are a lot of people having similar needs and would love to see something that is more ready to use. I am not experienced with ProCache, but I think being able to use ProCache to cache API output would not only be the most elegant way, but also one of the fastest possible. 

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Hi!

I'm having problems with the authorization.

I've installed the module and created a Double JWT-Application.

The Test-Route answers correct, so the module is working.

2022-08-28_17-30.png.515946a900d38add8cad4ad37a6240be.png

 

When i GET /api/auth/, also the correct answer appears.

2022-08-28_17-32.png.3aad6710f26a97a48f9d290ef3383254.png

But, when i POST /api/auth/ (x-api-key is set correctly), then i get this internal server error:

2022-08-28_17-33.thumb.png.81092e49246110211c6c2efb7e036b4a.png

I'm using ProcessWire 3.0.204 dev and PHP 8.1.6.

Any ideas how to fix this?

Thank you,
Christian

Link to comment
Share on other sites

Hey @paulbrause,

I managed to update my test-setup to ProcessWire 3.0.204 and PHP 8.1.1, but I cannot reproduce this error. Login via POST to /api/auth/ with a Basic Auth header still works fine. But of course I would still like to help you and fix a possible bug - maybe in a special edge case.

  1. Can you maybe downgrade your PHP version to 8.1.1 to rule out that it's not a bug regarding the PHP version?
  2. The error comes from a function call to the quote function of WireDatabasePDO. I do not call that function directly in AppApi, but it could be called from any other database function that I use. Can you please verify that the api-application that you created in ProcessWire's backend does not have any empty field? Are the secrets correctly set?

Thank you for using AppApi and I hope that we can quickly find the cause of this error!

Link to comment
Share on other sites

Hey @Sebi,

thanks for your quick response.

I downgraded PHP to version 8.1.1 and installed a clean PW v3.0.200 master and AppApi v1.2.3, but still no success.

It seems, that the secrets are correctly set.
AppApi-Settings.thumb.png.1061dc8337e2152a24b04b87ab046516.png

Always error 500. ?

AppApi-Error.thumb.png.54eb5f8eb088da77df0fceac28851367.png

But, the module created the Apptokens:

AppApi-AppToken.thumb.png.02e3075496d777b3e658010e72700941.pngAppApi-AppToken-Detail.thumb.png.1a6f23d9de7343dc05eafa37e7102706.png

Is there anything else i could have done wrong? ?‍♂️

Thank you,
Christian

Link to comment
Share on other sites

With AppApi's new version 1.2.4 we now use URL Path Hooks!
The old ProcessPageView::pageNotFound hook still remains, but is only used as a fallback if the ProcessWire version does not support the url path hooks. Thanks to @kongondo and @adrian who kept pushing me in the direction of including url path hooks!

I also revised the logging a little bit. In the access log (which can be activated via the module settings) the correct paths from the request are now entered. And an entry in the access log really only occurs if no error has occurred. Otherwise an entry is triggered in the appapi-exceptions log.

You can download the new version now in the ProcessWire modules page, Github or via auto-update in your ProcessWire UI. Thanks for using AppApi! ?

  • Like 4
  • Thanks 2
Link to comment
Share on other sites

A quick update... Version 1.2.5 allows you to deactivate url hooks and fallback into the legacy ProcessPageView::pageNotFound behavior. That's now possible in the module config.

I discovered, embarrassingly just after the release of the new version 1.2.4, a case where switching to the URL hook actually causes a breaking change. In all tests before this was not noticed, so sorry if anyone discovered something similar. Now, in any case, it is easy to switch back to the old hook. Now to the problem: Maybe someone reading this has some deeper insight and can help me to understand the issue.

I have a page on which I have included @Wanze`s SeoMaestro field and wanted to read the values from it via Api:

<?php
$page = wire('pages')->get('/');
if ($page->template->hasField('seo')) {
	$seoString = @$page->seo->render();
}

That actually works fine when it's done in an ProcessPageView::pageNotFound hook. But if I use a url hook and call it, the seo->render() call will throw the following error:

{
  "error": "Method Page::localUrl does not exist or is not callable in this context",
  "devmessage": {
    "class": "ProcessWire\\WireException",
    "code": 0,
    "message": "Method Page::localUrl does not exist or is not callable in this context",
    "location": "\/processwire\/wire\/core\/Wire.php",
    "line": 564
  }
}

I've managed to step through the code and find out the source of the exception. It's a call of page->localUrl in SeoMaestro's PageFieldValue class:
https://github.com/wanze/SeoMaestro/blob/master/src/PageFieldValue.php#L158

Any ideas? ?

  • Like 3
Link to comment
Share on other sites

  • 1 month later...

Hi, I maybe just found a very strange bug.

I'm using Processwire with a React front end and I setup it in a subdomain like so https://api.mydomain.com/  so just to avoid using api twice i changed the API endpoint into "v" using versions so my base api endpoint is https://api.mydomain.com/v/1/

Now, everything works fine except when I call a route with a GET parameter starting with "v", it cuts out the v from the slug, for example if I call

https://api.mydomain.com/v/1/category/variety the get parameter I get it's "ariety" and this happens on all characters I put in the api endpoint, not just for one character

This is the route I'm using

'category' => [
	['OPTIONS', '{slug:\S+}', ['GET']],
	['GET', '{slug:\S+}', Blog::class, 'getCategory',['application' => 1]], 
],

and this is the function which receives the parameter

 public static function getCategory($data) {
        $data = AppApiHelper::checkAndSanitizeRequiredParameters($data, ['slug|pageName']);
...

// $data->slug returns "ariety"

 

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...
On 10/12/2022 at 8:17 AM, Frank Vèssia said:

https://api.mydomain.com/v/1/category/variety the get parameter I get it's "ariety" and this happens on all characters I put in the api endpoint, not just for one character

Hi @Frank Vèssia,

I finally found time to recreate this once in my test environment. Unfortunately, I cannot reproduce the error.

My routes definition looks like yours:

$routes = [
	'v' => [
		'1' => [
			'category' => [
				['OPTIONS', '{slug:\S+}', ['GET']],
				['GET', '{slug:\S+}', AppApiTEST::class, 'getCategory'],
			]
		]
	]
];

When I simply dump $data->slug, I get the full "variety" slug when calling the /v/1/category/variety url:

class AppApiTest {
	public static function getCategory($data) {
		$data = AppApiHelper::checkAndSanitizeRequiredParameters($data, ['slug|pageName']);
		var_dump($data->slug);
		die();
	}
}

Can you try out if maybe my latest v1.2.6 update, where I improved the route-merging logic, fixed the issue for you? Or could it be something else which is special to your environment (PHP version? Modules or hooks, that could interfer with the AppApi handlers? Maybe it helps to deactivate the new ProcessWire URL Hook in AppApi's settings?)

  • Like 1
Link to comment
Share on other sites

19 hours ago, Sebi said:

Hi @Frank Vèssia,

I finally found time to recreate this once in my test environment. Unfortunately, I cannot reproduce the error.

My routes definition looks like yours:

$routes = [
	'v' => [
		'1' => [
			'category' => [
				['OPTIONS', '{slug:\S+}', ['GET']],
				['GET', '{slug:\S+}', AppApiTEST::class, 'getCategory'],
			]
		]
	]
];

When I simply dump $data->slug, I get the full "variety" slug when calling the /v/1/category/variety url:

class AppApiTest {
	public static function getCategory($data) {
		$data = AppApiHelper::checkAndSanitizeRequiredParameters($data, ['slug|pageName']);
		var_dump($data->slug);
		die();
	}
}

Can you try out if maybe my latest v1.2.6 update, where I improved the route-merging logic, fixed the issue for you? Or could it be something else which is special to your environment (PHP version? Modules or hooks, that could interfer with the AppApi handlers? Maybe it helps to deactivate the new ProcessWire URL Hook in AppApi's settings?)

mmm....I tried to update the module with no luck, at this point I don't know what it is...I also tried to deactivate some modules...anyway I will do some more test and let you know, thanks for now.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...