Core: [GraphQL] Use non nullable type for pagination types

Created on 6 Sep 2019  路  2Comments  路  Source: api-platform/core

Currently, collection query & edges are nullable & making it a bit more difficult to work with typescript. I think changing these 2 fields to non nullable would reduce the number of null checks for frontend:

    public function getResourcePaginatedCollectionType(GraphQLType $resourceType): GraphQLType
    {
        $shortName = $resourceType->name;

        if ($this->typesContainer->has("{$shortName}Connection")) {
            return $this->typesContainer->get("{$shortName}Connection");
        }

        $edgeObjectTypeConfiguration = [
            'name' => "{$shortName}Edge",
            'description' => "Edge of $shortName.",
            'fields' => [
                'node' => $resourceType,
                'cursor' => GraphQLType::nonNull(GraphQLType::string()),
            ],
        ];
        $edgeObjectType = new ObjectType($edgeObjectTypeConfiguration);
        $this->typesContainer->set("{$shortName}Edge", $edgeObjectType);

        $pageInfoObjectTypeConfiguration = [
            'name' => "{$shortName}PageInfo",
            'description' => 'Information about the current page.',
            'fields' => [
                'endCursor' => GraphQLType::string(),
                'startCursor' => GraphQLType::string(),
                'hasNextPage' => GraphQLType::nonNull(GraphQLType::boolean()),
                'hasPreviousPage' => GraphQLType::nonNull(GraphQLType::boolean()),
            ],
        ];
        $pageInfoObjectType = new ObjectType($pageInfoObjectTypeConfiguration);
        $this->typesContainer->set("{$shortName}PageInfo", $pageInfoObjectType);

        $configuration = [
            'name' => "{$shortName}Connection",
            'description' => "Connection for $shortName.",
            'fields' => [
-               'edges' => GraphQLType::listOf($edgeObjectType),
+               'edges' => GraphQLType::nonNull(GraphQLType::listOf(GraphQLType::nonNull($edgeObjectType))),
                'pageInfo' => GraphQLType::nonNull($pageInfoObjectType),
                'totalCount' => GraphQLType::nonNull(GraphQLType::int()),
            ],
        ];

-       $resourcePaginatedCollectionType = new ObjectType($configuration);
+       $resourcePaginatedCollectionType = GraphQLType::nonNull(new ObjectType($configuration));
        $this->typesContainer->set("{$shortName}Connection", $resourcePaginatedCollectionType);

        return $resourcePaginatedCollectionType;
    }

Most helpful comment

Having those as non-nullable would be against the Relay pagination spec. See https://facebook.github.io/relay/graphql/connections.htm#sec-Connection-Types and https://github.com/graphql/graphql-relay-js/issues/185#issuecomment-387923487

The Stage 3 optional chaining feature in JS makes dealing with nullable values very straightforward -- just 1 extra character.

All 2 comments

Having those as non-nullable would be against the Relay pagination spec. See https://facebook.github.io/relay/graphql/connections.htm#sec-Connection-Types and https://github.com/graphql/graphql-relay-js/issues/185#issuecomment-387923487

The Stage 3 optional chaining feature in JS makes dealing with nullable values very straightforward -- just 1 extra character.

Ah I see, seems like optional chaining is coming in the next version of Typescript as well.

Was this page helpful?
0 / 5 - 0 ratings