Skip to content

Plans for cppgraphqlgen 4.0 #172

Closed
@wravery

Description

@wravery

This is where I'm going to start tracking features for 4.0, the next major version of cppgraphqlgen. This will be a breaking change for existing consumers, so it's an opportunity to cleanup deprecated methods and simplify some of the APIs. I'm also going to adopt C++20 features if they are well enough supported on Windows, Linux, and macOS.

  • Stand up a branch for 4.0 and start making PRs against that: https://github.com/microsoft/cppgraphqlgen/tree/next.
  • C++20: Co-routines Implemented in https://github.com/microsoft/cppgraphqlgen/tree/next.
  • Finer grained asynchrony Substitute a custom awaitable instead of passing a std::launch enum value to allow plugging in a custom thread pool for example.
  • C++20: Concepts In progress, used for type-erasure (see below), but still more use cases to consider.
  • Type Erasure instead of inheritance Implemented in https://github.com/microsoft/cppgraphqlgen/tree/next. Solves const methods prevent storing context in subclasses #171 and makes the design much more decoupled. Depends on C++20 Concepts for the conditional handling of stubs which may be unimplemented on the target type.
  • Use specific types for interfaces and unions instead of service::Object Generate type-erased objects for interface types, and return std::variant<> for the options in a union.
  • Simplified code gen by removing options or making new defaults (e.g. --no-stubs by default, type erased headers instead of inheritance, etc.).
  • Add CMake functions to module config which help with codegen targets (Unable to use cppgraphqlgen #170) Particularly schemagen --separate-files. Might be able to make --separate-files the only option to simplify schemagen and improve incremental build times.
  • Otherwise modernize CMake Bump the minimum required version as necessary, remove fallbacks and global config variables for earlier versions. Partially implemented in https://github.com/microsoft/cppgraphqlgen/tree/next.
  • Make separate .cpp files include only the ...Object.h headers that they reference in their return types. Tweak headers to make compilation faster #156
  • Update to the recently released https://spec.graphql.org/October2021/ version of GraphQL itself.
  • Export a target for RapidJSON internal details Could be done with a minor version update, but should be implemented in 4.0 at the latest: Export writeResponse and SubscriptionKey based delivery #169.
  • Allow returning std::shared_ptr<T> from getters and avoid/defer memory copies in response::Value See discussion below. Type-Erasure can make this cleaner since you can actually make that the return type of the getter, but it should work in 3.0 as well where the getters all return service::FieldResult.
  • Update docs

I've decided to postpone adopting these C++20 features because support is still uneven, and several of them require using compiler flags to enable them:

  • C++20: Modules Pending, requires support in CMake, should make compilation of templates faster.
  • C++20: Ranges Pending, should modernize a lot of begin/end iterator usage.
  • C++20: std::fmt instead of std::ostringstream Pending, may require update to MSVC for standards errata.

This proved too complicated. Since FieldResult (now AwaitableScalar/AwaitableObject) uses the modified type wrapped in std::vector and std::optional, it can't just wrap the result in a known service::Object type-erased wrapper. To make this work, the field accessor return type would need to be parameterized with all of the same modifiers as ModifiedResult instead of the C++ type, which would make deciphering the correct type to use in a field accessor implementation much harder:

  • Implicitly convert to type-erased objects in service::FieldResult We should be able to just return the std::shared_ptr<T> and let service::FieldResult wrap it, since it knows the expected type-erased object type. Even better, could it implicitly handle conversions of the value_type in std::vector or std::optional, and nest the convertible types that way? The logic in service::ModifiedResult seems to suggest it's possible.

I'll update this list as new features crop up and as I/we make progress on it.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions