Wire up a Spring application
The Java half is a Spring Boot application depending on qlive, which
brings the GraphQL schema assembly and jOOQ with it. qlive-test is the reference wiring.
What QLive provides
Section titled “What QLive provides”QLiveConfiguration is a @Configuration that contributes:
| Bean | |
|---|---|
BootstrapService |
assembles the config, CSRF token and injections for a path |
GraphQL |
built from the domain’s schema |
ConditionParser |
parses FilterDSL JSON into the condition model |
It requires a QLiveDomain bean and a StaticAnalysisProvider bean from
your application.
The static analysis provider is required, not optional. Without one the
bootstrap service could not tell which paths declare noSchema(), and a
null from a provider has to keep meaning one thing – “not ready yet, ask
again” – rather than doubling as “this application never configured one”.
Forgetting the bean gets you a missing-bean failure at startup instead of
pages that answer 503 forever.
The domain
Section titled “The domain”The QLiveDomain bean is yours: it is built from your jOOQ schema, your logic
beans and your metadata providers. See
Define the domain.
Static analysis, per profile
Section titled “Static analysis, per profile”@Profile("dev")@Beanpublic DevStaticAnalysisProvider devStaticAnalysisProvider(){ return new DevStaticAnalysisProvider();}
@Profile("prod")@Beanpublic ProdStaticAnalysisProvider prodStaticAnalysisProvider(){ return new ProdStaticAnalysisProvider();}The dev provider holds what the Vite dev server has pushed so far – a push
carries the modules one save changed, and the provider merges it into the
rest; the production one reads track-usage.json from the classpath, where
the Maven build puts Vite’s output. The production one is also where an application’s
use of the analysis is checked: the whole of it is present before the
first request, so a build whose injections are not where they belong fails
at startup rather than on the page that happens to hit the mistake. The dev
provider reports the same thing and carries on – you are mid-edit.
Page rendering
Section titled “Page rendering”@Beanpublic VitePageRenderer vitePageRenderer(){ return new VitePageRenderer(bootstrapService);}
@Beanpublic ViteIndexController viteIndexController(VitePageRenderer renderer){ return new ViteIndexController(bootstrapService, renderer);}ViteIndexController serves everything below the Vite base, hands Vite’s
emitted assets back to static resource handling, and answers
/api/bootstrap and /api/update. Share one VitePageRenderer across
controllers – it caches the entry point templates, which only change when
the frontend is rebuilt.
The GraphQL endpoint
Section titled “The GraphQL endpoint”@Beanpublic GraphQLController graphQLController(GraphQL graphQL){ return new GraphQLController(graphQL);}/graphql is under normal Spring Security protection including CSRF. There
is a second, dev-only endpoint exempt from CSRF, enabled with the dev
profile.
Dev-only: receiving the pushed analysis
Section titled “Dev-only: receiving the pushed analysis”The dev provider above is what the Vite plugin pushes into. The endpoint
receiving that push is one more bean, dev only as well:
@Bean@Profile("dev")public TrackUsageDevController trackUsageDevController( DevStaticAnalysisProvider provider) { ... }vite build writes track-usage.json to disk for the backend to read, but
vite dev never touches disk. So in dev the plugin pushes the analysis
here instead, and this is what the backend answers page requests from –
which query a view injects, which paths declared noSchema().
A push carries only the modules one save changed; the plugin collects them
for pushDebounceMs first. Nothing is generated here: the
query result types are written
by the plugin, in the frontend, where the sources are.
Query logic
Section titled “Query logic”See Expose document queries
for the document query bean – one generic method with @QLiveTypeParam
covers every type.
Security
Section titled “Security”The security configuration is yours, and three of its rules are QLive’s. See Secure an application – the dev endpoints in particular are open until you close them.