Is it possible to access argument subfield in graphql query? - schema

I'm looking for a way of accessing the subfield of query argument (object) without passing it as a separate argument.
Here is the detailed case which explains why I need this.
I have the following schema:
type Query {
users(input: getUsersInput!):[User]
}
type User {
_id: ID!
name: String!
isAdmin(platformId: ID!)
}
type getUsersInput {
platformId: ID!
search: String
#...some other query params
}
So now I want to query users for of specific platform and check if they are admins. Something like that:
query getUsers($input: getUsersInput!) {
users(input: $input) {
_id
name
isAdmin(platformId: $input.platformId)
}
}
However referencing platformId with $input.platformId gives an error.
I can pass platformId into the query as an extra argument, but I'd like to avoid.
I guess the solution might be in several directions:
There is another syntax/way of getting access to the subfield of a query argument. However, I haven't seen any example of it.
Build a schema or queries another way.
Would be happy to get any help and thoughts on this.

Related

Expected Name found { ; tring to find objects with specific field value

I'm trying to get familiar with graphql. So I have an entity called Car in BE. And I have only Cars exposed.
Now I'm trying to find all the cars from Cars, where year(launch) is certain say 2001. It's actually a variable. Now I think the following query should work.
query GetCars($y: String!) {
cars({ year: $y }) {
id
year
}
}
But it gives me error saying, Expected Name found {, it throws the error at the second dollar sign.
filters and where is also undefined.
Can anyone give me some hint to resolve this problem?
Using: GraphiQL
In cars({ year: $y}) the name of your argument is missing - arguments always need to have a name in GraphQL and the name of your arguments and their GraphQL type are defined in your schema.
Assuming your cars fields has an argument called year in your schema, you need to rewrite your query to: cars(year: $y).
Assuming your cars fields has a filter or something like that defined in the schema and that filter expects an input object type that has - maybe among others - a field year, you would write: cars(filter: { year: $y }).

How to create array of object in JSON from data in SQL table by SQL query?

I want to create array of object in json from sql query. So I created the SQL query as follows :
Select society as Society,
(select Name as [ID.FirstName],schoolName as [School.School_Name] from Details for json path ) as Students
From Details
For json path, WITHOUT_ARRAY_WRAPPER
I wanted my JSON result should look like this:
{ "Society":"England",
"Students":[
{
"Id":{
"FirstName":"Harry"
}
},
{
"School":{
"School_Name":"St.Stephan School"
}
}
]
}
I am getting the different output but I know this is not the generic way to write the code.
{ "Society":"England",
"Students":[
{
"Id":{
"FirstName":"Harry"
},
"School":{
"School_Name":"St.Stephan School"
}
}
]
}
Can somebody please help me out?
I think this will work...
select [Name] as [ID.FirstName], schoolName as [School.School_Name]
from Details
for json path, root('Students')
I looked at the MS docs for the "for json" command. I don't think you need to split up your select fields the way you did. Also, I added the brackets around "Name" because memory is telling me that it's a reserved word, and you can force it to treat it as a field name with the brackets.

Can I compose two JSON Schemas in a third one?

I want to describe the JSON my API will return using JSON Schema, referencing the schemas in my OpenAPI configuration file.
I will need to have a different schema for each API method. Let’s say I support GET /people and GET /people/{id}. I know how to define the schema of a "person" once and reference it in both /people and /people/{id} using $ref.
[EDIT: See a (hopefully) clearer example at the end of the post]
What I don’t get is how to define and reuse the structure of my response, that is:
{
"success": true,
"result" : [results]
}
or
{
"success": false,
"message": [string]
}
Using anyOf (both for the success/error format check, and for the results, referencing various schemas (people-multi.json, people-single.json), I can define a "root schema" api-response.json, and I can check the general validity of the JSON response, but it doesn’t allow me to check that the /people call returns an array of people and not a single person, for instance.
How can I define an api-method-people.json that would include the general structure of the response (from an external schema of course, to keep it DRY) and inject another schema in result?
EDIT: A more concrete example (hopefully presented in a clearer way)
I have two JSON schemas describing the response format of my two API methods: method-1.json and method-2.json.
I could define them like this (not a schema here, I’m too lazy):
method-1.json :
{
success: (boolean),
result: { id: (integer), name: (string) }
}
method-2.json :
{
success: (boolean),
result: [ (integer), (integer), ... ]
}
But I don’t want to repeat the structure (first level of the JSON), so I want to extract it in a response-base.json that would be somehow (?) referenced in both method-1.json and method-2.json, instead of defining the success and result properties for every method.
In short, I guess I want some kind of composition or inheritance, as opposed to inclusion (permitted by $ref).
So JSON Schema doesn’t allow this kind of composition, at least in a simple way or before draft 2019-09 (thanks #Relequestual!).
However, I managed to make it work in my case. I first separated the two main cases ("result" vs. "error") in two base schemas api-result.json and api-error.json. (If I want to return an error, I just point to the api-error.json schema.)
In the case of a proper API result, I define a schema for a given operation using allOf and $ref to extend the base result schema, and then redefine the result property:
{
"$schema: "…",
"$id": "…/api-result-get-people.json",
"allOf": [{ "$ref": "api-result.json" }],
"properties": {
"result": {
…
}
}
}
(Edit: I was previously using just $ref at the top level, but it doesn’t seem to work)
This way I can point to this api-result-get-people.json, and check the general structure (success key with a value of true, and a required result key) as well as the specific form of the result for this "get people" API method.

"Cannot return null for non-nullable type: 'Person' within parent 'Messages' (/getMessages/sendBy)" in GraphQL SDL( aws appsync)

Iam new to graphql.Iam implementing a react-native app using aws appsync.Following is the code i have written in schema
type Messages {
id: ID!
createdAt: String!
updateAt: String!
text: String!
sendBy: Person!
#relation(name: "UserMessages")}
type Person {
id: ID!
createdAt: String!
updateAt: String!
name: String!
messages: [Messages!]!
#relation(name: "UserMessages")}
When i tried to query the sendBy value it is giving me an error saying
query getMessages{
getMessages(id : "a0546b5d-1faf-444c-b243-fab5e1f47d2d") {
id
text
sendBy {
name
}
}
}
{
"data": {
"getMessages": null
},
"errors": [
{
"path": [
"getMessages",
"sendBy"
],
"locations": null,
"message": "Cannot return null for non-nullable type: 'Person' within parent 'Messages' (/getMessages/sendBy)"
}
]
}
Am not understanding that error please help me.Thanks!! in Advance
This might sound silly, but still, developers do this kind of mistakes so did I. In subscription, the client can retrieve only those fields which are outputted in the mutation query. For example, if your mutation query looks like this:
mutation newMessage {
addMessage(input:{
field_1: "",
field_2: "",
field_n: "",
}){
field_1,
field_2
}
}
In the above mutation since we are outputting only field_1 & field_2. A client can retrieve the only subset of these fields.
So if in the schema, for a subscription if you have defined field_3 as required(!), and since you are not outputting field_3 in the above mutation, this will throw the error saying Cannot return null for non-nullable type: field_3.
Looks like the path [getMessages, sendBy] is resolving to a null value, and your schema definition (sendBy: Person!) says sendBy field cannot resolve to null. Please check if a resolver is attached to the field sendBy in type Messages.
If there is a resolver attached, please enable CloudWatch logs for this API (This can be done on the Settings page in Console, select ALL option). You should be able to check what the resolved Request/Response mapping was for the path [getMessages, 0, sendBy].
I encountered a similar issue while working on my setup with CloudFormation. In my particular situation I didn't configure the Projection correctly for the Global Secondary Indexes. Since the attributes weren't projected into the index, I was getting an ID in the response but null for all other values. Updating the ProjectionType to 'ALL' resolved my issue. Not to say that is the "correct" setting but for my particular implementation it was needed.
More on Global Secondary Index Projection for CloudFormation can be found here: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-projectionobject.html
Attributes that are copied (projected) from the source table into the index. These attributes are additions to the primary key attributes and index key attributes, which are automatically projected.
I had a similar issue.
What happened to me was a problem with an update resolver. I was updating a field that was used as GSI (Global Secondary Index). But I was not updating the GSI, so when query by GSI the index exists but the key for that attribute had changed.
If you are using Dynamo DB, you can start debugging there. You can check the item and see if you have any reference to the primary key or the indexes.
I had a similar issue.
for me the problem was lying with the return type of the schema . As i was doing a query with PK on dynamodb table ..it was returning a list of items or data you can say . but in my schema i had a schema define as a singular struct format .
Error was resolved when i just made the return type in schema as list of items .
like
type mySchema {
[ID]
}
instead of
type mySchema
{
id : ID!
name : String!
details : String!
}
This error is thrown for multiple reasons . so your reason could be else but still i just posted one of the scenarios.

ObjectFilter in SoftLayer doesn't work

I find ObjectFilter doesn't work in SoftLayer.
I even tried the example provided in the SoftLayer webpage here:
https://sldn.softlayer.com/article/object-filters
REST:
List the ID and hostname of all servers in dal05
https://api.softlayer.com/rest/v3/SoftLayer_Account/getVirtualGuests?objectMask=mask[id,hostname]&objectFilter={"datacenter":{"name":{"operation":"dal05"}}}
When I ran this command, it still returns all the virtual guests, regardless what data center that virtual guest belongs to.
try this request:
GET https://api.softlayer.com/rest/v3/SoftLayer_Account/getVirtualGuests?objectMask=mask[id,hostname,datacenter]&objectFilter={"virtualGuests":{"datacenter":{"name":{"operation":"dal05"}}}}
The issue with your request is that you are missing the "virtualGuests" property, keep in mind that the objectFilter is filtering over the data in the database, so you need to tell it over what table work and over what record of the table work. e.g. using the "SoftLayer_Account" that implies that all the work will be over the "SoftLayer_Account" table now you need to tell id over what property/record of that table work in this case you need to work over the "virtualGuests" and so on. Please keep in mind that and you review the documentation about the valid properties/records e.g. these are the valid properties/record for Softlayer_Account:
http://sldn.softlayer.com/reference/datatypes/SoftLayer_Account
Regards
Maybe you can try adding virtualGuestsin the filter, something like this:
objectFilter={ "virtualGuests": { "datacenter": { "longName": { "operation": "Dallas 6" } } } }
or please see the first examples of https://sldn.softlayer.com/article/object-filters, like this:
object_filter = {
'virtualGuests': {
'datacenter': {
'name': {'operation': 'dal05'}
}
}
}