Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add degraphql entity support #1346

Open
mheap opened this issue Jul 23, 2024 · 6 comments
Open

Add degraphql entity support #1346

mheap opened this issue Jul 23, 2024 · 6 comments
Assignees

Comments

@mheap
Copy link
Member

mheap commented Jul 23, 2024

Add support for configuring degraphql entities using Deck.

https://docs.konghq.com/hub/kong-inc/degraphql/#3-configure-degraphql-routes-on-the-service

This may require changes in go-database-reconciler too

@mheap
Copy link
Member Author

mheap commented Oct 29, 2024

The KIC team recently added generic support using KongCustomEntity for schemas added by plugins. I recommend reading https://docs.konghq.com/kubernetes-ingress-controller/latest/guides/services/custom-entity/ to see how it works.

The important part is:

apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  namespace: default
  name: degraphql-example
plugin: degraphql
config:
  graphql_server_path: /v1/graphql
---
apiVersion: configuration.konghq.com/v1alpha1
kind: KongCustomEntity
metadata:
  namespace: default
  name: degraphql-route-example
spec:
  type: degraphql_routes
  fields:
    uri: "/contacts"
    query: "query{ contacts { name } }"
  controllerName: kong
  parentRef:
    group: "configuration.konghq.com"
    kind: "KongPlugin"
    name: "degraphql-example"

The spec.type field in the second config indicates the Kong entity name, and everything under fields is passed as the configuration.

This would translate to something similar to the following in deck:

plugin_entities:
  - plugin: my-degraphql-plugin
    entity: degraphql_routes
    fields:
      uri: "/contacts"
      query: "query{ contacts { name } }"
  - plugin: my-degraphql-plugin
    entity: degraphql_routes
    fields:
      uri: "/bookings"
      query: "query{ bookings { id, cost } }"
  - plugin: different-plugin
    entity: some-plugin-entity
    fields:
      foo: bar

@mheap
Copy link
Member Author

mheap commented Nov 28, 2024

Building this in an generic way is a lot of effort in DB-backed modes (months).

Let's pivot to supporting degraphql only in the next version, but make sure that the configuration structure we design for the YAML file will work for other plugins too

@Prashansa-K
Copy link
Contributor

@mheap I have chosen the following yaml format for degraphql-routes (and other subsequent custom entities):

It is similar to what you had suggested above with minor changes -

plugin_entities:
  - type: <ENTITY-TYPE>
    plugin: <Plugin name or id>
    fields:
      - <array of entity-specific fields>

For example, for degraphql-plugin this would look like

plugin_entities:
  - type: degraphql_routes
    plugin: my-depgraphql-plugin
    fields:
      uri: "/contacts"
      query: "query{ contacts { name } }"
      service: ef947e50-515c-4464-8eba-0f26b58ded80

Let me know if any changes are necessary here.

As of now, I am ensuring that most of the operations happen in a generic way so that expanding for other entities is easier. I will push a branch for the same soon. POC is complete and I am working on code-improvements and tests. Prior to that, if you have any suggestions for file inputs, I can add those in the code.

@mheap
Copy link
Member Author

mheap commented Dec 16, 2024

LGTM. Is service a degraphql property? I only see uri and query in https://docs.konghq.com/hub/kong-inc/degraphql/#available-endpoints

@Madi-Ji
Copy link

Madi-Ji commented Dec 16, 2024

Hey team,

Quick heads-up, speaking of degraphQL properties, methods is also important
Even though it isn't properly listed in our plugin doc

It is probably important to highlight that degraphQL plugin manage more complex GQL queries than query{ contacts { name } },
such as mutations that uses as variables objects and arrays and various searches for example.

query SearchPosts($filters: PostsFilters) {
  posts(filter: $filters) {
    id
    title
    author
  }
}

In these scenarios, GET method (default method) isn't suitable to use

Some folks are using this properly to tell degraphQL plugin to handle POST request and parse a JSON body

Example

Plugin config:

curl -X POST https://admin.api.local/services/foo/degraphql/routes \
  --data uri='/search/posts' \
  --data methods='POST' \ # ⬅️
  --data query='query SearchPosts($filters: PostsFilters) {
  posts(filter: $filters) {
    id
    title
    author
  }
}'

Usage:

curl --request POST \
  --url https://api.local/foo/search/posts \
  --header 'Content-Type: application/json' \
  --data '{ date: { between: { min: "2025-01-01", max: "2025-02-01" } } }'

curl --request POST \
  --url https://api.local/foo/search/posts \
  --header 'Content-Type: application/json' \
  --data '{
  "id": {
    "in": [
      "7cf342f2",
      "9860193d",
      "63498e1a"
    ]
  }
}'

By the way, method is an array / table and can be either or both GET & POST
Meaning the deck file would probably look like this :

plugin_entities:
  - type: degraphql_routes
    plugin: my-degraphql-plugin
    fields:
      uri: "/search/posts"
      methods: 
        - "POST"
      query: |
        query SearchPosts($filters: PostsFilters) {
          posts(filter: $filters) {
            id
            title
            author
          }
        }
      service: "<id>"  # service id, TBC

@Prashansa-K
Copy link
Contributor

Update:
Not all plugin_entities are tightly coupled with plugins. degraphql_routes also doesn't hold any plugin info. Thus, I am removing the plugin field from the config. If required by other entities, it can become a part of the "fields".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants