Azure / data-api-builder

Data API builder provides modern REST and GraphQL endpoints to your Azure Databases and on-prem stores.
https://aka.ms/dab/docs
MIT License
930 stars 193 forks source link

[Bug]: Relationships not working with SWA #1667

Open atyshka opened 1 year ago

atyshka commented 1 year ago

What happened?

Relationships are not working for me with GraphQL and SWA.

Here is what my graphql schema looks like:

type Submission @model {
  id: ID!
  personId: ID! 
  condition: String!
  tests: [Test]
  history: [Timestamp]
}

type Person @model {
  id: ID!
  condition: String!
}

I want to make a relationship with the Person and submission, so I added this to my database config file:

    "Person": {
      "source": "participant-container",
      "permissions": [
        {
          "actions": ["*"],
          "role": "anonymous"
        }
      ],
      "relationships": {
        "submissions": {
          "cardinality": "many",
          "target.entity": "Submission",
          "source.fields": ["id"],
          "target.fields": ["personId"]
        }  
      }
    },

Using this test query:

    query getPersons {
      people {
        items {
          id
          condition
          submissions {
            items {
              id
            }
          }
        }
      }
    }

I get this result: graphql.error.graphql_error.GraphQLError: Cannot query field 'submissions' on type 'Person'

Why isn't the relationship working? I shouldn't need to make any changes to my gql schema, right? The DAB docs show how to add a relationship but I haven't seen anything similar in SWA. I would assume it works exactly the same though, the only change necessary is in the config file, right?

To clarify, I am testing on the swa dev server, not the deployed SWA app.

Version

0.7.6+61de247acf65280d93783072226f695536591ffb

What database are you using?

CosmosDB NoSQL

What hosting model are you using?

Static Web Apps (SWA)

Which API approach are you accessing DAB through?

GraphQL

Relevant log output

[swa] POST http://localhost:5000/graphql (proxy)
[dataApi] info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
[dataApi]       Request starting HTTP/1.1 POST http://localhost:4280/graphql application/json 1415
[dataApi] info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
[dataApi]       Executing endpoint 'Hot Chocolate GraphQL Pipeline'
[dataApi] info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
[dataApi]       Executed endpoint 'Hot Chocolate GraphQL Pipeline'
[swa] POST http://localhost:4280/graphql - 200
[dataApi] info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
[dataApi]       Request finished HTTP/1.1 POST http://localhost:4280/graphql application/json 1415 - 200 - application/json;+charset=utf-8 3.3330ms

Code of Conduct

atyshka commented 1 year ago

To clarify, I am not using the dab CLI, I am directly updating the config file since I'm using SWA. I assume that's all the CLI is doing, if I am wrong and I need the CLI to properly form relationships, let me know

severussundar commented 1 year ago

Hey @atyshka, at the moment, relationships are not supported for CosmosDB NoSQL. Relationships are applicable only for SQL database types.

To be able to successfully execute the query you have mentioned in your example, the Submissions entity needs to be embedded within the People entity. Here's a relevant link for the same ~ Cosmos DB Data Modeling

Also, the type definitions in the schema file needs to reflect that. So, the schema file would look like this

type People @model(name:"People") {
    ...
    submissions: [Submission]
}

type Submission @model(name: "Submission"){
   ...
}
atyshka commented 1 year ago

I see. This would definitely be a useful feature to add. On a separate note, what is the "name" parameter that you are passing to @model? I have not seen that param in any of the documentation

Aniruddh25 commented 1 year ago

@atyshka, the @model directive is utilized to establish a correlation between the GraphQL object type in the schema you provide and the corresponding entity name in the runtime config. The directive is formatted as: @model(name:"<Entity_Name>"). The name parameter for the @model directive represents the name of the entity in your configuration file. It is only required if you were the name of your entity differs from the name of the corresponding GraphQL object type.

For e.g., in your case if your entity Person were to have GraphQL type as Pupil your type definition would change as follows assuming the config stays the same:

type Pupil @model(name:"Person") {
    ...
    submissions: [Submission]
}

with the config entry:

"Person": {
      "source": "participant-container",
      "permissions": [
        {
          "actions": ["*"],
          "role": "anonymous"
        }
      ]

Hope this answers your question. We are in the process of updating the documentation with regards to @model as well.