Jump to content

GraphQL for ProcessWire


dadish

Recommended Posts

  • 2 weeks later...

Hello !

Thank you for this very nice module @dadish

I'm trying to get the ProField RepeaterMatrix to work based on this fork here by Tulios link.

But I'm having a hard time, struggling for some days deciphering the complex GraphQL architecture and logging everything in the console haha

I really would like to use it like this screenshot below, with fragments for every repeater matrix types.

 

image.png.1d5f91e5f5971e25745556bc1f10268a.png

 

The main issue I have is I can't find a way to build the list of every possible templates types.

The way RepeaterMatrix works is it is differentiating the types based on the repeater_matrix_type. It doesn't seem to work with templates. I tried to use the constructor `new Template()` to create some based on this property but I don't know where to add this line.

Also should I create a new RepeaterMatrixPageArrayType based on your PageArrayType?

Any chance you would take a look? I know it's a ProField, but if you got some time I would be very grateful

  • Like 1
Link to comment
Share on other sites

Hello @Matoseb,

I haven't used any of the pro fields, myself. So I don't know much about them. But conceptually they should be very similar to list of pages.

4 hours ago, Matoseb said:

The way RepeaterMatrix works is it is differentiating the types based on the repeater_matrix_type. It doesn't seem to work with templates. I tried to use the constructor `new Template()` to create some based on this property but I don't know where to add this line.

You should take a closer look what I do in PageType. I create the fields of the page by inspecting it's template. I don't know what kind of API the repeater_matrix_type has, but I suspect similar. But even then, I have a separate type generator for each supported field. If RepeaterMatrix does not use those as underlying FieldType classes, then you'll have to recreate for each of them on your own.

5 hours ago, Matoseb said:

Also should I create a new RepeaterMatrixPageArrayType based on your PageArrayType?

Yes, but the bulk of the work would be implementing the equivalent of PageType that would be responsible for creating types for each repeater_matrix_type. The PageArrayType simply wraps the PageType into an array and adds things like pagination, first item, last item, total count, etc.

5 hours ago, Matoseb said:

Any chance you would take a look? I know it's a ProField, but if you got some time I would be very grateful

Sorry bud. The ProFields are out of the scope of this plugin.

Link to comment
Share on other sites

On 1/2/2022 at 12:55 AM, ngrmm said:

UPDATE: seems it has something to do with my site-settings
I tried it in JS and it works

Glad to see you progressed on this.

On 1/2/2022 at 12:55 AM, ngrmm said:

However when I use /graphql/ as URL i see an object in the console. When I use /processwire/setup/graphql/ I see a json in the console

The /processwire/setup/graphql/ is for internal/admin use only. You should focus on the /graphql/ endpoint.

Link to comment
Share on other sites

Thank you dadish for you infos, that was fast

I'll try again soon!

1 hour ago, dadish said:

I haven't used any of the pro fields, myself. So I don't know much about them. But conceptually they should be very similar to list of pages.

Yes, they are based on the Repeaters. It contains a list of pages of the same template, but with repeater_matrix_type  differentiating the different possible entries.

1 hour ago, dadish said:

I don't know what kind of API the repeater_matrix_type has, but I suspect similar.

The repeater_matrix_type field is a FieldtypeInteger

Link to comment
Share on other sites

Good news !

I managed to add some good support for ProField RepeaterMatrix.

Github link (experimental, use at your own risk!)

Todo

  • Only allow possible fields per matrix types in the schema.
  • Add matrix type as names and not as integers. Easier to read.
  • Support for mutations / inputfields.
  • Repeater Depth/Indents -> Need to add feature to FieldTypeRepeater.

However I can't share it as a third party module. You have to insert the php file manually.

This is due to the static method field() {} not being called from a third party module. Feature request? ?

BTW @dadish I couldn't find a way to add invisible types to the Schema during construction. I tried to use the modifySchema hook, but no luck. Could be useful

  • Like 1
Link to comment
Share on other sites

  • 1 year later...

What is the best way to avoid naming conflicts when querying Option-Select Field with values starting with numbers, which breaks the Schema. This occures when adding the (options) field in the module config screen for fields to serve.

Link to comment
Share on other sites

  • 4 weeks later...

 

On 4/18/2023 at 2:28 PM, martind said:

What is the best way to avoid naming conflicts when querying Option-Select Field with values starting with numbers, which breaks the Schema. This occures when adding the (options) field in the module config screen for fields to serve.

Hey @martind,

So I looked into this and it looks like it's not possible. The values for the FieldtypeOptions are described in Enums. The values for the Enums in GraphQL spec should conform to the GraphQL Name. Which must start with a letter and followed by zero or more letters and/or numbers. So an option in the FieldtypeOptions that starts with or only have digits will not compile properly.

Link to comment
Share on other sites

On 5/14/2023 at 8:36 PM, dadish said:

 

Hey @martind,

So I looked into this and it looks like it's not possible. The values for the FieldtypeOptions are described in Enums. The values for the Enums in GraphQL spec should conform to the GraphQL Name. Which must start with a letter and followed by zero or more letters and/or numbers. So an option in the FieldtypeOptions that starts with or only have digits will not compile properly.

hi dadish,
first of all thank you for this great module, very imposing. I saw the specs, the problem here is, that i have this values and have to provide it over the api for an upcoming expansion step. Isn't it possible to add such fields with a getQueryFields hook instead the modules field configuration? How do you handle such cases for existing sites and data?
thank you and best wishes!
martin

Link to comment
Share on other sites

1 hour ago, martind said:

i have this values and have to provide it over the api for an upcoming expansion step. Isn't it possible to add such fields with a getQueryFields hook instead the modules field configuration? How do you handle such cases for existing sites and data?

Not sure tbh. I would create an alias field. Create the a similar field. If your field is called `options` call the alias field `options_graphql`. Set the same set of options to your alias field, but make sure to have their title be prefixed with some word. So if your options are `1, 2, 3` then have your alias options `gql_1, gql_2, gql_3` or similar. Add the `options_graphql` field into graphql. Then use hooks to synchronize the two fields when page is saved and loaded with `Pages:saveReady` and `Page:loaded` hooks.

  • Like 1
Link to comment
Share on other sites

  • 4 months later...

Hi @dadish,

I've been using your module since 2018, and it's been really solid, thanks for all your work.

I wonder if you can help with a recent issue I've had since updating Processwire core from 3.0.200 to 3.0.227+?

I have a single mutation which creates a new page, and its fields are a mix of text fields, number fields, and page reference fields. Since updating PW core, the mutation hangs, and the only error I see is a 504 Timeout. The site seems to completely lock up as well when there's a pending query.

Is there anything you can suggest to help debug this?  I'm running v2.0.0.

Thanks,
Tom

PS -

I've done a little more digging. I get the same problem with 1.4.1 and 2.0.0. There's no problem in PW 3.0.222, it only happens with 3.0.223 and higher.

Here are a couple of screenshots showing the error in the GraphiQL tool - one with the error on 3.0.229, and one where it works on 3.0.200.

Interestingly, although I get an error on 3.0.229, the page is created successfully, it just isn't reported as a success.

successful request on PW 3-0-200.png

unsuccessful request on PW 3-0-229.png

Link to comment
Share on other sites

Hey @sodesign

On 10/4/2023 at 4:46 PM, sodesign said:

I wonder if you can help with a recent issue I've had since updating Processwire core from 3.0.200 to 3.0.227+?

I tested the module against the latest ProcessWire(3.0.229) and it works. It performs mutations. See the screenshot below.

My best guess is that there is something doesn't work with your custom mutation. But it's hard to find out what it is, because I don't know what it does.

The error message points to the graphiql client script. But I am not sure why it's failing for you and not for me.

One thing I can suggest is to debug this without the graphiql. Make the request from your script and log the response/error and see if that gives some more insight.

Meanwhile I'll try to upgrade the graphiql to the latest version. Maybe that will solve your problem.

Screenshot 2023-10-08 at 11.19.19.png

Link to comment
Share on other sites

Thank you for the pointers. I checked a new simple mutation on a different template and it was all ok.

I checked the hooks we have running on the ConfiguratorQuote template I used in the original mutation and managed to find the problem. Surprisingly it was to do with a page saved hook ending up in an infinite loop. I'm not sure why it wasn't happening on the earlier core version but that's not a discussion for this board!

Thanks for your help and looking into it so quickly 🙂  

Link to comment
Share on other sites

Is there a way to query any page based on their url?

This, without even knowing their template name.

Like this

# generic page selector?
page(s: "url=/mypage/") {
    first {
      name
      ...on basicPage {
      	title
      }
      ...on projectPage {
      	title
        text_area
      }
    }
 }

 

Link to comment
Share on other sites

On 10/14/2023 at 5:09 PM, Matoseb said:

Is there a way to query any page based on their url?

This, without even knowing their template name.

No, we don't have that ability. We had it as an experimental feature in initial version of the module. But we dropped it because of the security concerns.

Could you describe a hypothetical, real world example where you would need it? If I am convinced that it is a popular use case I might consider adding it back.

Link to comment
Share on other sites

  • 2 weeks later...
On 7/7/2021 at 5:18 AM, dadish said:

Login should work as regular processwire login flow. Just do a first request as

{
	login(name: "username", pass: "password") {
    	statusCode
    }
}

Then all subsequent requests from the browser will automatically include the processwire cookies.

hi dadish.
i have some content queries that get executed as guest, later comes a login query.
after that, the previous content queries further get executed as guest (with the old session id), where eg. the me query gives me the correct user data.
so the guest session remains in place for all queries executed before login.
What is the beste way to prevent this?
thanks martin

Link to comment
Share on other sites

13 minutes ago, martind said:

i have some content queries that get executed as guest, later comes a login query.
after that, the previous content queries further get executed as guest (with the old session id), where eg. the me query gives me the correct user data.
so the guest session remains in place for all queries executed before login.
What is the beste way to prevent this?

Not entirely sure if I understood you correctly. Once you login, subsequent requests will include the session cookies that were set by ProcessWire.

If you want to omit cookies for certain requests, then you probably can explicitly exclude cookies in your ajax calls? For example if you're using fetch api, you can omit the credentials when executing a request.

Link to comment
Share on other sites

thanks for the fast reply.
i don't really have acces to the client apps code, just see my logs from graphql template. So the app makes a few queries as guest, then a login, then further queries. All queries  done before the login, are further logged as guest with the old session id. All queries that havent been executed before login, are logged for the logged-in user with another session_id. So the app now has 2 clients. When quering access restricted contents it comes to problems.

So, do i have a possibility on the serverside to prevent this?

Link to comment
Share on other sites

1 hour ago, martind said:

So, do i have a possibility on the serverside to prevent this?

Prevent what exactly? I'm still trying to understand what you're trying to achieve. You want all those requests to log under a single session id? Because it's the same person?

1 hour ago, martind said:

When quering access restricted contents it comes to problems.

What kind of problems? The logged out user gets access to restricted content which you want to prevent? Or the logged in user can't get the content that it should have access to?

Link to comment
Share on other sites

sorry.

first: yes, it's the same person
second: logged in user can't get the content that it should have access to.

i don't think it's a problem with the module, in postman everything works finde. the session consists. But the react app seems to do here something diffrent.

Link to comment
Share on other sites

3 minutes ago, martind said:

i don't think it's a problem with the module, in postman everything works finde. the session consists. But the react app seems to do here something diffrent.

Most likely the react app is not including the cookie headers in it's requests. Like I mentioned before, sometimes you need to explicitly include them. Like for the fetch api you need to set credentials option to "include".

Link to comment
Share on other sites

  • 4 months later...

Hello!

First, I would like to mention that I love this module... not having to write my own queries and mutations is a life-saver and makes managing a backend API very easy.

With that said, I wouldn't be here if I didn't have any issues with it.

 

These are my 2 main issues:

  • It's very hard to deal with the naming conventions. I have a dropdown field with a few values, which isn't an issue, but these fields also include special characters (like brackets, dollar signs, etc...). Upon adding the field in ProcessGraphQL setup, I get an error:
    Quote

    {
      "errors": "Names must only contain [_a-zA-Z0-9] but \"Raven (GPRS)\" does not."
    }

    I could obviously solve this by renaming the options in my dropdown but that would break functionality in other places and would make my work a lot harder. I'm wondering if there is any other approach to this besides renaming the dropdown values.
  • Maybe unrelated to ProcessWire, I'm running a Vue application that executes queries using Axios on my PW backend. Initially, I kept getting a CORS related error: 
    Quote

    Access to XMLHttpRequest at 'http://localhost/xxxx/graphql/' from origin 'http://localhost:5173' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

     I managed to "fix" it by adding the following snippet to my GraphQL template, that I got from here (thanks @dadishhttps://github.com/dadish/ProcessGraphQL/blob/622c9db61cb7cf3ef998edb31e4e0e47b3c96669/test/server.php
    function cors() {
    
      // Allow from any origin
      if (isset($_SERVER['HTTP_ORIGIN'])) {
          // Decide if the origin in $_SERVER['HTTP_ORIGIN'] is one
          // you want to allow, and if so:
          header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
          header('Access-Control-Allow-Credentials: true');
          header('Access-Control-Max-Age: 86400');    // cache for 1 day
      }
    
      // Access-Control headers are received during OPTIONS requests
      if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    
          if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
              // may also be using PUT, PATCH, HEAD etc
              header("Access-Control-Allow-Methods: GET, POST, OPTIONS");         
    
          if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
              header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
    
          exit(0);
        }
    }
    
    cors();

    Unfortunately, this introduced a new issue: When I use the 'login' query from my front-end (and it logs in successfully), the session isn't saved and the next query won't be authenticated and will throw an error. This is usually fixed if I just add 'withCredentials: true' to my Axios setup but if I do that, I reintroduce the same CORS error from before. I also tried specifying the host for the Origin header but it makes no difference. I have no idea how to approach this. Here is my Axios setup for reference: 

    // graphQL client setup
    const graphqlClient = axios.create({
      baseURL: 'http://localhost/xxx/graphql/',
      withCredentials: true,
      headers: {
          'Content-Type': 'application/json',
          'Access-Control-Allow-Origin': 'http://localhost:5173'
      },
    });

     

If by any chance I happen to fix these issues by myself, I will post a reply on how I tackled them.

Any help appreciated,

Thanks in advance,

CrazyAppel

  • Like 1
Link to comment
Share on other sites

I was just curious if anyone has tried installing this lately and ran into any problems regarding "Module requirements are not fulfilled so installing may cause problems."..  The module page lists that the required versions is >= 3.0.62 but when I go to install the module it is saying >= 3.0.210 is required. I am currently running 3.0.98 and if I go through with the install I get a warning regarding that I am not meeting the processwire requirements. It seems to install just fine, but I was just worried of creating other issues if I proceeded.

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...