How to handle cacheing with big nested objects - graphql

I have a graphql object that has a bunch of nested object fields like the following:
object{
field1
field2
field3
field4 {
field4.1
field4.2 {
field4.2.1
}
}
field5 {
field5.1{
field 5.1.1
field 5.1.2
}
}
field 6
field 7
}
The issue is that for field4 and field5 there is no unique identifier for them and they are always unique to the object. I don't want it to try to cache these objects and instead just cache the whole object since the child fields are unique to the parent object.
How do I tell me client that I dont want to try and cache these child fields and instead just cache the object as a whole?

I did the following to get around this
const blackList = new Set()
new InMemoryCache({
dataIdFromObject: (o: any) => {
if (o.__typename != null) {
if (cacheBlacklist.has(o.__typename)) {
return null
}
...
}

Related

GraphQL only returning one item from array instead of all items

I have a GraphQL query which is meant to return a full array list containing 9 items, but it's only returning 1 item. This is an Array of Objects.
If I console log data.dataJson it returns the first Object in the array as an Object, not Array...
I'm new to using GraphQL so any pointers would be appreciated!
Query
export const ProjectsQuery = graphql`
query IndexQuery {
dataJson {
title
img
type
category
url
}
}
`;
So the issue was down to having an unnamed array in the JSON. Changing to the following fixed the issue:
{
"projects": [
{
...
}
]
}

Graphql Filter by query

So I'm trying to learn graphql I've been playing around with the ENS subgraph on the graph
I've figured out how to do simple filtering but when I try to write more complex filters they do not compile.
I'm trying to get the top 5 transactions for the each of the top 5 domains. (e.g for each domain I want the top 5 transactions)
{
#Sample Query to get the first 5 domains (not needed for question but used to validate results)
domains(first: 5) {
id
name
labelName
labelhash
}
#attempt to filter the transfer.domain.id by TOP 5 domains.id
transfers(where: { domain { id: domains(first: 5) { id } } }) {
id
domain {
id
}
blockNumber
transactionID
}
}
EDIT I'm going to attempt to simplify my request since I'm not sure nesting queries is possible. How can I filter an inner query by Id:
transfers(where: {domain.id: "0x9c0fc2519ae862cee27778e5c34714d6c7e3ca21ad572df47ad9f6fe530909bd"}) {
id
domain {
id
}
blockNumber
transactionID
}
NOTE: Domain.Id = does not compile how would I write a filtered query like that?
However, My filter doesn't compile syntactically. How can I write a query which filters by a child property?
You can query like this
query {
getPost(id: "0x1") {
title
text
datePublished
}
}
Got this from https://dgraph.io/docs/graphql/queries/search-filtering/

insert items into array using graphql - Parse server

I have a class that contains a field called 'notes'. Its data type is array. In the mutation, I'm able to save data on the field. problem is it overwrites the value. I want to add value in the array. how do I do it? here's my mutation. I know I'm not doing the right thing, but can't find it in the documentation as well
mutation {
updateParcel(input: { id: "B6aESEwWcA", fields: { notes: ["wow"]}}) {
parcel {
objectId
notes {
... on Element {
value
}
}
}
}
}

How to check record is fully empty on left join in jooq query

I try to fetch a record from table with left join on another table. An information in the second table can be not found but I expect an information from the first table.
val citizenship = Tables.COUNTRIES.`as`("citizenship")
try {
return context.selectFrom(Tables.CLIENT_PROJECTIONS
.leftJoin(citizenship).on(
Tables.CLIENT_PROJECTIONS.CITIZENSHIP_COUNTRY_CODE.eq(
citizenship.CODE_ALPHA2
)
)
).where(Tables.CLIENT_PROJECTIONS.ID.eq(id)).fetchOne {
val clientProjection = ClientProjectionMapper.map(it.into(Tables.CLIENT_PROJECTIONS)) ?: return#fetchOne null
clientProjection.citizenship = CountryMapper.map(it.into(citizenship))
clientProjection
}
} catch (ex: DataAccessException) {
logger.error("Failed to access to database", ex)
throw ex
}
I convert data from CountriesRecord to Entity in CountryMapper:
object CountryMapper : RecordMapper<CountriesRecord, Country> {
override fun map(record: CountriesRecord?): Country? = when {
record != null -> {
Country(
countryCode = record.codeAlpha,
title = record.title
)
}
else -> {
null
}
}
}
But if query returns null in every fields of CountriesRecord my map method receive a non-nullable entity but everyone fields of this entity is empty.
I can check every field of CountriesRecord is it null but i think that isn't good idea. Can I check it by another more best way? May be I should write more correct query to database?
A LEFT JOIN in SQL does exactly that. It produces nulls for all columns of the left joined table for which there was no match in the join's ON clause.
You don't have to check whether each column is null. The primary key will be good enough, because that should have a NOT NULL constraint on it, meaning that if the primary key value is null (record.codeAlpha), then that must be because of the LEFT JOIN.
Change your second mapper to this:
object CountryMapper : RecordMapper<CountriesRecord, Country> {
override fun map(record: CountriesRecord?): Country? = when {
record?.codeAlpha != null -> {
Country(
countryCode = record.codeAlpha,
title = record.title
)
}
else -> {
null
}
}
}

How to sort on nested field in graphql ruby?

How do I sort on a nested field (or a virtual attribute) in graphql-ruby?
ExampleType = GraphQL::ObjectType.define do
name 'Example'
description '...'
field :nested_field, NestedType, 'some nested field' do
// some result that is virtually calculated and returns
OpenStruct.new(a: 123//some random number, b: 'some string')
end
end
QueryType = GraphQL::ObjectType.define do
name 'query'
field: example, ExampleType do
resolve -> (_obj, args,_ctx) {
Example.find(args['id']) //Example is an active record
}
end
field: examples, types[ExampleType] do
resolve -> (_obj, args,_ctx) {
// NOTE: How to order by nested field here?
Example.where(args['id'])
}
end
end
And if I am trying to get a list of examples ordered by nested_field.a:
query getExamples {
examples(ids: ["1","2"], order: 'nested_field.a desc') {
nested_field {
a
}
}
}
You can not order Active record by virtual attribute, because Active record can not match this virtual attribute to SQL/NoSQL query. You can avoid limitation, by creating view at DB layer. In GraphQL, sorting/pagination should be implemented at DB layer. Without that sorting/pagination implementation queries all data from DB to application memory.
Also, I want to recommend you switching from order argument with string type to sort argument with [SearchSort!] type based on enums. GraphQL schema will looks like that:
input SearchSort {
sorting: Sorting!
order: Order = DESC
}
enum Sorting {
FieldName1
FieldName2
}
enum Order {
DESC
ASC
}
It helps you implement mapping from GraphQL subquery to DataBase query.

Resources