Skip to content

Commit

Permalink
Add support for resolvers without fragments
Browse files Browse the repository at this point in the history
Summary:
Remove validation for `rootFragment` on the resolver definition.

- With this we can expose plain functions as GraphQL fields
- With this we can extend object with client fields that may return Client or Server Objects.

Reviewed By: josephsavona

Differential Revision: D37119681

fbshipit-source-id: 203fd3e99d68096532b9eb3e45f661766da2402a
  • Loading branch information
alunyov authored and facebook-github-bot committed Jun 14, 2022
1 parent 735c496 commit 7d5cc34
Show file tree
Hide file tree
Showing 10 changed files with 623 additions and 20 deletions.
8 changes: 0 additions & 8 deletions compiler/crates/relay-docblock/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,6 @@ impl RelayResolverParser {
}
let live = self.fields.get(&LIVE_FIELD).copied();
let root_fragment = self.get_field_with_value(*ROOT_FRAGMENT_FIELD)?;
if live.is_none() && root_fragment.is_none() {
self.errors.push(Diagnostic::error(
ErrorMessages::MissingField {
field_name: *ROOT_FRAGMENT_FIELD,
},
ast.location,
));
}
let fragment_definition = root_fragment
.map(|root_fragment| {
self.assert_fragment_definition(root_fragment.value, definitions_in_file)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,6 @@ graphql`

✖︎ Missing docblock field "@fieldName"

/path/to/test/fixture/relay-resolver-missing-multiple-fields.invalid.js:10:3
10 │ *
│ ^
11 │ * @RelayResolver
│ ^^^^^^^^^^^^^^^^^
12 │


✖︎ Missing docblock field "@rootFragment"

/path/to/test/fixture/relay-resolver-missing-multiple-fields.invalid.js:10:3
10 │ *
│ ^
Expand Down
127 changes: 126 additions & 1 deletion packages/react-relay/__tests__/ClientOnlyQueries-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const {
Environment,
Network,
RecordSource,
RelayFeatureFlags,
Store,
commitLocalUpdate,
createOperationDescriptor,
Expand All @@ -48,7 +49,17 @@ function createEnvironment(
});
}

describe('Client Only Queries', () => {
beforeEach(() => {
RelayFeatureFlags.ENABLE_RELAY_RESOLVERS = true;
RelayFeatureFlags.ENABLE_CLIENT_EDGES = true;
});

afterEach(() => {
RelayFeatureFlags.ENABLE_RELAY_RESOLVERS = false;
RelayFeatureFlags.ENABLE_CLIENT_EDGES = false;
});

describe('Client-only queries', () => {
let renderer;
let environment: IEnvironment;

Expand Down Expand Up @@ -217,3 +228,117 @@ describe('Client Only Queries', () => {
);
});
});

test('hello-world query', () => {
const environment = createEnvironment(RecordSource.create(), () => {
const error = new Error('Unexpected Network Error');
throw error;
});

function InnerTestComponent(props: {|fetchPolicy?: FetchPolicy|}) {
const data = useLazyLoadQuery(
graphql`
query ClientOnlyQueriesTest2Query {
hello(world: "World")
}
`,
{},
{
fetchPolicy: props.fetchPolicy ?? 'store-only',
},
);
return data.hello ?? 'MISSING';
}

function TestComponent({
environment: relayEnvironment,
...rest
}: {|
environment: IEnvironment,
fetchPolicy?: FetchPolicy,
|}) {
return (
<RelayEnvironmentProvider environment={relayEnvironment}>
<React.Suspense fallback="Loading...">
<InnerTestComponent {...rest} />
</React.Suspense>
</RelayEnvironmentProvider>
);
}
let renderer;
TestRenderer.act(() => {
renderer = TestRenderer.create(
<TestComponent
environment={environment}
fetchPolicy="store-or-network"
/>,
);
});

expect(renderer?.toJSON()).toBe('Hello, World!');
});

test('hello user query with client-edge query', () => {
const environment = createEnvironment(
RecordSource.create({
'client:root': {
__id: 'client:root',
__typename: '__Root',
'node(id:"4")': {__ref: '4'},
},
'4': {
id: '4',
__id: '4',
name: 'Alice',
},
}),
() => {
const error = new Error('Unexpected Network Error');
throw error;
},
);

function InnerTestComponent(props: {|fetchPolicy?: FetchPolicy|}) {
const data = useLazyLoadQuery(
graphql`
query ClientOnlyQueriesTest3Query {
hello_user(id: "4") @waterfall {
name
}
}
`,
{},
{
fetchPolicy: props.fetchPolicy ?? 'store-only',
},
);
return `Hello, ${data.hello_user?.name ?? 'MISSING'}!`;
}

function TestComponent({
environment: relayEnvironment,
...rest
}: {|
environment: IEnvironment,
fetchPolicy?: FetchPolicy,
|}) {
return (
<RelayEnvironmentProvider environment={relayEnvironment}>
<React.Suspense fallback="Loading...">
<InnerTestComponent {...rest} />
</React.Suspense>
</RelayEnvironmentProvider>
);
}
let renderer;
TestRenderer.act(() => {
renderer = TestRenderer.create(
<TestComponent
environment={environment}
fetchPolicy="store-or-network"
/>,
);
});

expect(renderer?.toJSON()).toBe('Hello, Alice!');
});

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 7d5cc34

Please sign in to comment.