Skip to content

Conversation

MathieuDutSik
Copy link
Contributor

Motivation

GraphQL is the canonical way to access Wasm application state on Linera. Therefore, it is of paramount
importance of having excellent support for GraphQL in the linera-views.

The canonical way of handling missing values in a query is to return null. Ignoring it and pretending that it was
not queried is not the recommended way. This is for example visible on GraphQL Search and Filter – How to search and filter results with GraphQL.
In this exposition, we see that the GraphQL schema types are

type Query {
  album(id: ID!): Album
  albums(genre: Genre, ids: [ID!]): [Album]! 
}

The meaning of that schema is that the function album returns something that may be null, and that albums returns a list of entries that may be null. This is because by default in GraphQL a variable can be nulled. If not it has a postfix of "!".

The GraphQL standard does not say that if a request is failing to return null. However, if returning null is not allowed, then in case of a missing key, you should return null at a higher level. See GraphQL, Section 7.1.2. Therefore for our case, it is better to return a null value in case of missing key.

Proposal

The Entry is changed in order to have a value that is an Option<V>. The change go surprisingly smoothly.

Test Plan

The CI.

Due to the importance of GraphQL in Linera applications, a specific smart contract has been created for which we can test the

Release Plan

This changes are also relevant to the Game Of Life test.

Links

See above.

@MathieuDutSik MathieuDutSik marked this pull request as ready for review October 9, 2025 14:21
@MathieuDutSik MathieuDutSik requested review from Twey and ma2bd October 9, 2025 14:21
counter = { path = "../../../examples/counter" }
counter-no-graphql = { path = "../../../examples/counter-no-graphql" }
create-and-call = { path = "./create-and-call" }
graph-ql-queries = { path = "./graph-ql-queries" }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: let's be consistent with the spelling graphql.


// READ1

for (query, expected_response) in [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to use insta here (with the snapshot identifier being the query).

> {
pub key: K,
pub value: V,
pub value: Option<V>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really convinced that map entry values should always be optional. E.G. when iterating over sets of entries (perhaps with entries with a filter other than keys) we should just skip missing entries, so the value should be non-optional.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now, the object filters does not implement any significant filter. You have only two options: either None with all keys returned or the keys being selected.

Maybe, the filters are meant to be extended to a larger feature. If so, I have not seen a description of it as a GitHub issue. But then, the real question is what actually would be possible as filters:

  • What we are considering is the CollectionView / ReentrantCollectionView function. The input type I and view type V are generic. So, how exactly can we input a meaningful filter?
  • The page GraphQL search and filter gives some examples like (a) => a.genre == genre with a of the output type. How could we implement a filtering function on the view?
  • It does not appear that the async-graphql library has any functionality for filtering. So, I do not know if we could implement filtering in a generic way without some major engineering effort.

I have three other reasons for returning null in case of missing values:

  • The change is putting the behavior of CollectionView / ReentransCollectionView in line with MapView. Right now the MapView is returning null for missing keys. I think it is important to have MapView<K,V> as near to CollectionView<K,RegisterView<V>> as possible.
  • The change of returning null on missing values is extending the functionality. It is not breaking anything. All of the tests that were passing are still passing.
  • In the page GraphQL search and filter the schema for the filtering is "albums(input: AlbumsInput): [Album]! " and so it does return nullon missing keys.

All that being said, I do not see this work as a final work on GraphQL for linera-views. For example, cursors, intervals, or similar are definitely needed. It is possible to add those functionalities since they operate in a generic way. But we have to be clear about what is realistic to implement in linera-views.

@MathieuDutSik MathieuDutSik changed the title Add support for "null" in case of missing values and add integration test for Add support for "null" in case of missing values and add integration test for GraphQL Oct 16, 2025
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

Successfully merging this pull request may close these issues.

2 participants