Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Node interface id field to be configurable. #3638

Closed
wants to merge 7 commits into from

Conversation

kesne
Copy link
Contributor

@kesne kesne commented Nov 13, 2021

This adds a new option to the Rust compiler, nodeInterfaceIdField, which allows customization of the Node interface's id field. I initially tried to determine this via inference, but it's entirely possible that the Node interface has multiple id fields, so I figured explicitly specifying it made more sense.

@orta
Copy link
Contributor

orta commented Dec 11, 2021

( +1-ing the desire for this, lots of OSS JS/graphQL tooling takes over id or makes it hard to get the right table to query for an id. At Artsy there was so much interacting with legacy systems we had id (table), _id(db) and then __id which was finally the one we could use for GQL object identification )

@maraisr
Copy link
Contributor

maraisr commented Dec 11, 2021

We'd also need to let the relay-runtime know about that property, as so much hangs on that ID field 😅

@kesne
Copy link
Contributor Author

kesne commented Dec 14, 2021

@maraisr From what I can tell, getDataID should be able to be used to accomplish that:

@maraisr
Copy link
Contributor

maraisr commented Dec 14, 2021

Just a ripe ol pain, coz in places where there is no id field, relay still tries to normalise like serialising some input arguments and such. I've not looked too close, but would suspect this method to have to implement all of those avenues as well?

@facebook-github-bot
Copy link
Contributor

@alunyov has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

Copy link
Contributor

@alunyov alunyov left a comment

Choose a reason for hiding this comment

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

Thanks for adding this! Sorry, we dropped the ball on this PR and did not review it earlier.

The main feedback is that let's try re-using FeatureFlags for this id field configuration.

@@ -341,7 +341,7 @@ impl CompilerState {
.any(|sources| !sources.processed.is_empty())
}

fn is_change_safe(&self, sources: &SchemaSources) -> bool {
fn is_change_safe(&self, sources: &SchemaSources, project_config: &ProjectConfig) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

can we add node_interface_id_field to the compiler_state itself?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried to do this, but the config that's used to create the compiler_state is the root config, not the project config, so this seemed challenging to try to move.

@@ -363,7 +363,7 @@ impl CompilerState {
&current,
&Vec::<(&str, SourceLocationKey)>::new(),
) {
Ok(schema) => schema_change.is_safe(&schema),
Ok(schema) => schema_change.is_safe(&schema, project_config.node_interface_id_field),
Copy link
Contributor

Choose a reason for hiding this comment

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

then here we can pass self. node_interface_id_field

@@ -843,6 +851,9 @@ struct ConfigFileProject {

#[serde(default)]
js_module_format: JsModuleFormat,

#[serde(default)]
pub node_interface_id_field: Option<StringKey>,
Copy link
Contributor

Choose a reason for hiding this comment

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

can we add comment here, and also to the compiler README.md that explains the purpose of this field

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, I think this is something from the internal discussion about this PR.

I think we should add this field to FeatureFlags here:
https://github.com/facebook/relay/blob/59c9bc01c1d215b75d6c683f6ee1074a8110fd7b/compiler/crates/common/src/feature_flags.rs

And this PR (or this can be a separate PR) should just add feature_flags to SingleProjectConfigFile.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can make the change to move this to feature flags. I didn't originally since it seems like all of the feature flag config was resolved to boolean values, whereas this is a string configuration value, which didn't seem to me like a feature flag.

Copy link
Contributor

Choose a reason for hiding this comment

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

this is a string configuration value, which didn't seem to me like a feature flag.

Fair point.

I general, I think this field is similar with ConnectionInterface. I think both of these should be defined on the project_config here:

let project_config = ProjectConfig {
name: project_name,
base: config_file_project.base,
enabled: true,
schema_extensions: config_file_project.schema_extensions,
output: config_file_project.output,
extra_artifacts_output: config_file_project.extra_artifacts_output,
shard_output: config_file_project.shard_output,
shard_strip_regex,
schema_location,
typegen_config: config_file_project.typegen_config,
persist: config_file_project.persist,
variable_names_comment: config_file_project.variable_names_comment,
extra: config_file_project.extra,
test_path_regex,
feature_flags: Arc::new(
config_file_project
.feature_flags
.unwrap_or_else(|| config_file_feature_flags.clone()),
),
filename_for_artifact: None,
skip_types_for_artifact: None,
rollout: config_file_project.rollout,
js_module_format: config_file_project.js_module_format,
};

Something like schema_configuration field which is a struct:

struct SchemaConfiguration {
  connection_interface: ConnectionInterface,
  node_interface_id_field: Option<StringKey>,
}

But this refactoring can be done independently from this PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

or schema_config for short, as we already have typegen_config.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@alunyov I moved it to a FeatureFlag, just so you can see what that would be like. Let me know which approach you'd like to move forward with!

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks @kesne! I importing this internally.

@@ -130,6 +134,7 @@ fn apply_common_transforms(
program: Arc<Program>,
connection_interface: &ConnectionInterface,
feature_flags: Arc<FeatureFlags>,
Copy link
Contributor

Choose a reason for hiding this comment

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

the benefits of adding node_interface_id_field to FeatureFlags is that you already have them in apply_transforms so it's less changes.

@facebook-github-bot
Copy link
Contributor

@alunyov has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@alunyov
Copy link
Contributor

alunyov commented Dec 16, 2021

So, moving this to feature_flags didn't make it cleaner.

And I totally agree with you @kesne that it doesn't seem right to have these settings in the feature_flags. All these suggestions were with the idea that we somehow add this id_field_name without passing this individual property around too much.

One problem was, we could not use ProjectConfig type in the relay-transforms, as it was defined in the relay-compiler crate. I've moved ProjectConfig to a separate crate so we can use this type both in relay-compiler and in relay-transforms. See: 5baad8c

I'm working on updates to apply_transform that will make them accept project_config, these change should land soon.

I will also add new property on the ProjectConfig - schema_config where we can put node_interface_id_field.

@alunyov
Copy link
Contributor

alunyov commented Dec 17, 2021

The changes to the project_config landed. I think we can add the id_field_name to the schema_config here:

https://github.com/facebook/relay/blob/main/compiler/crates/relay-config/src/project_config.rs#L42-L44

@alunyov
Copy link
Contributor

alunyov commented Dec 17, 2021

A quick update. I think there will be another iteration on top of the schema_config. We need it also here: #3121 (comment) - so I think I'll add it directly to program: it would be easier to access these configs in various transforms.

facebook-github-bot pushed a commit that referenced this pull request Jan 11, 2022
Summary:
A follow-up for this PR: #3638

Pass schema configuration to `relay-typegen` and use the `id` name for the config.

Reviewed By: kassens

Differential Revision: D33479397

fbshipit-source-id: 617d341609c0749ca2e6921b74a6354508f70455
@Lalitha-Iyer
Copy link
Contributor

@alunyov There could be pagination bug Related to this pr. If we configure the compiler to use a custom id, I found pagination loadNext fails at runtime, as it queries with node.id and not the custom configured node id.
Looking at the source we probably need to change paginationVariables.id to paginationVariables.identifierField
https://github.com/facebook/relay/blob/main/packages/react-relay/relay-hooks/useLoadMoreFunction.js#L212

Let me know if I should have a more sandboxed example and a new issue.

@Emilios1995
Copy link
Contributor

@alunyov There could be pagination bug Related to this pr. If we configure the compiler to use a custom id, I found pagination loadNext fails at runtime, as it queries with node.id and not the custom configured node id. Looking at the source we probably need to change paginationVariables.id to paginationVariables.identifierField https://github.com/facebook/relay/blob/main/packages/react-relay/relay-hooks/useLoadMoreFunction.js#L212

Let me know if I should have a more sandboxed example and a new issue.

@Lalitha-Iyer I opened an issue for this already. Sadly I haven't had time to debug and the issue hasn't received much attention.

@Lalitha-Iyer
Copy link
Contributor

@Emilios1995 Appreciate you opening an issue. I will follow along.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants