retracedhq/retraced

Can't include custom `fields` in GraphQL response

Tchekda opened this issue · 9 comments

What steps did you take and what happened:

Create a log with the following payload:

{
  "action": "some.record.created",
  "group": {
    "id": "test"
  },
  "crud": "c",
  "created": "2024-04-04T20:51:29.457Z",
  "source_ip": "127.0.0.1",
  "actor": {
    "id": "485573",
    "name": "Tchekda",
    "fields": {
        "div": "FR"
    }
  },
  "target": {
    "id": "100",
    "fields": {
        "div": "RU"
    }
  },
  "is_failure": true,
  "fields": {
      "div": "FR"
  }
}

Make the following request to the Publisher API:

query Search($query: String!, $last: Int, $before: String) {
    search(query: $query, last: $last, before: $before) {
        totalCount
        pageInfo {
            hasPreviousPage
            hasNextPage
        }
        edges {
            cursor
            node {
                id
                action
                crud
                created
                received
                canonical_time
                description
                actor {
                    id
                    name
                    href
                    fields {
                        div
                    }
                }
                group {
                    id
                    name
                }
                target {
                    id
                    name
                    href
                    type
                    fields {
                        div
                    }
                }
                display {
                    markdown
                }
                is_failure
                is_anonymous
                source_ip
                country
                loc_subdiv1
                loc_subdiv2
                fields {
                     div
                }
            }
        }
    }
}

What did you expect to happen: The custom fields should be returned in the response.

Any relevant output that will help us better understand what's going on:

When the custom div field is removed from the GraphQL query, I get a 200 Response but obviously my custom fields aren't included

Error logs:

[PublisherAPI.graphqlPost:f005481c] !! 500 TypeError: Cannot read properties of undefined (reading 'name')\n    at Object.Field (/app/src/handlers/graphql/handler.ts:57:61)\n    at Object.enter (/app/node_modules/graphql/language/visitor.js:301:32)\n    at Object.enter (/app/node_modules/graphql/utilities/TypeInfo.js:391:27)\n    at visit (/app/node_modules/graphql/language/visitor.js:197:21)\n    at validate (/app/node_modules/graphql/validation/validate.js:91:24)\n    at validateQuery (/app/src/handlers/graphql/handler.ts:86:26)\n    at graphQL (/app/src/handlers/graphql.ts:35:31)\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n    at PublisherAPI.graphqlPost (/app/src/controllers/PublisherController.ts:323:20)

Anything else you would like to add:

Seems like the second part of this line https://github.com/retracedhq/retraced/blob/main/src/handlers/graphql/handler.ts#L57 is causing issues as the type of div isn't strictly defined in the code

Environment:

  • Retraced version: Latest stable Docker image
  • SDK: Not used

@Tchekda You can only add custom fields as part of fields (which are indexed) or metadata (which is not indexed). And then in GraphQL you can use fields.<custom field> or metadata.<custom field> (not for queries since metadata is not indexed).

And then in GraphQL you can use fields.<custom field>

I tried to use the following query but it doesn't work (gives Syntax Error: Unexpected character: \".\".):

query Search($query: String!, $last: Int, $before: String) {
    search(query: $query, last: $last, before: $before) {
        totalCount
        pageInfo {
            hasPreviousPage
            hasNextPage
        }
        edges {
            cursor
            node {
                id
                action
                crud
                created
                received
                canonical_time
                description
                actor {
                    id
                    name
                    href
                    fields.div
                }
                group {
                    id
                    name
                }
                target {
                    id
                    name
                    href
                    type
                }
                display {
                    markdown
                }
                is_failure
                is_anonymous
                source_ip
                country
                loc_subdiv1
                loc_subdiv2
            }
        }
    }
}

@Tchekda You can only add custom fields as part of fields (which are indexed) or metadata (which is not indexed). And then in GraphQL you can use fields.<custom field> or metadata.<custom field> (not for queries since metadata is not indexed).

The issue seems to be that the GraphQL response template cannot include custom fields as that request would not pass validation. Not about the search string.

@Tchekda You can only add custom fields as part of fields (which are indexed) or metadata (which is not indexed). And then in GraphQL you can use fields.<custom field> or metadata.<custom field> (not for queries since metadata is not indexed).

The issue seems to be that the GraphQL response template cannot include custom fields as that request would not pass validation. Not about the search string.

Exactly, seems like I can't include custom fields into the response template. Which is quite problematic as I would love to have them there. Even more I would really love to be able to filter by them, once I get them in the reply ;)

Thanks for reporting this, definitely sounds like an issue. @ukrocks007 will investigate.

In the meantime could you please try

                    fields {
                        key
                        value
                    }

I think fields and metadata is all or nothing, you won't be able to selectively bring the keys in there.

Indeed it worked and returned:

fields: {
    {
        "key": "div",
        "value": "FR"
    }
}

Now the question is: how can I filter based on the those fields, as they are "indexed" ?

@Tchekda Cool. Only the outer fields attribute is indexed though. You will be able to search on those in the search query string by using fields.div.

Works like a charm, thank you for your help !
As I understood from the docs and asked on Discord, I can't use commas to list multiple div, it's only reserved to the fields listed here ?