Skip to content

Add GraphQL support: foundation and catalog query resolvers#14

Open
devin-ai-integration[bot] wants to merge 7 commits intodevelop-7.0.xfrom
devin/1776896218-graphql-catalog-foundation
Open

Add GraphQL support: foundation and catalog query resolvers#14
devin-ai-integration[bot] wants to merge 7 commits intodevelop-7.0.xfrom
devin/1776896218-graphql-catalog-foundation

Conversation

@devin-ai-integration
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration Bot commented Apr 22, 2026

Overview

Introduces initial GraphQL support in broadleaf-framework-web, covering both the shared infrastructure (Ticket 1) and catalog-side query/field resolvers (Ticket 2). Existing REST controllers are untouched.

What's in this PR

Dependencies

  • Adds spring-boot-starter-graphql to core/broadleaf-framework-web/pom.xml and the root <dependencyManagement>.
  • Pins org.reactivestreams:reactive-streams to 1.0.4 and excludes the transitive 1.0.3 pulled in by graphql-java / java-dataloader to satisfy the enforcer's DependencyConvergence rule.

Foundation (org.broadleafcommerce.core.web.graphql)

  • GraphQLContextInterceptorWebGraphQlInterceptor that resolves a customerId from the customerId header or query parameter, loads the customer via CustomerService, and populates CustomerState. Falls back to an anonymous customerService.createCustomer() when no identity is provided (mirroring RestApiCustomerStateFilter).
  • GraphQLExceptionResolver — extends DataFetcherExceptionResolverAdapter and maps AddToCartException, PricingException, OfferMaxUseExceededException, IllegalCartOperationException, RemoveFromCartException, UpdateCartException to stable errorCode values in the error extensions; everything else becomes INTERNAL_ERROR.
  • src/main/resources/graphql/schema.graphqls — schema for Query, Mutation, Product, Category, Sku, ProductOption/ProductOptionValue, Order/OrderItem/OrderItemAttribute, FulfillmentGroup/FulfillmentGroupItem, Address, OrderPayment, Customer, a Money object type, a BigDecimal scalar, and input types for cart/shipping/billing.
  • src/main/resources/graphql-application.properties — sets spring.graphql.graphiql.enabled, spring.graphql.path=/graphql, and spring.graphql.schema.locations=classpath:graphql/.

Resolvers (org.broadleafcommerce.core.web.graphql.resolvers)

  • CatalogQueryResolver@QueryMapping methods for product, productByExternalId, productByUri, products, category, categoryByUri, categories, sku, skuByUpc, delegating to CatalogService.
  • SearchQueryResolversearch query builds a SearchCriteria (query, pageSize, startIndex, derived page) and calls SearchService.findSearchResults.
  • CategoryFieldResolver — lazy @SchemaMapping for Category.activeSubCategories and Category.products.
  • ProductFieldResolver — lazy @SchemaMapping for Product.defaultCategory, defaultSku, additionalSkus, productOptions.
  • SkuFieldResolver@SchemaMapping for Sku.salePrice, retailPrice, cost returning Broadleaf Money, plus Money.currency mapping Currency to its ISO code.

Verification

mvn compile -pl core/broadleaf-framework-web -am -q -DskipTests passes locally.

Things worth a careful look

  1. graphql-application.properties is not auto-imported. Spring Boot only loads application.properties/application.yml automatically. Because broadleaf-framework-web is a library, downstream apps will need to spring.config.import=classpath:graphql-application.properties (or equivalent) for these settings to take effect. Confirm this matches the intended consumption model.
  2. BigDecimal scalar is declared in the schema but no scalar is wired in code. graphql-java does not ship a BigDecimal scalar by default, so schema initialization could fail at runtime in an app that actually boots this. If the intent is to rely on graphql-java-extended-scalars, that dependency is not added here; happy to follow up in this PR if desired.
  3. Anonymous customer creation in the interceptor. customerService.createCustomer() writes a new Customer on every request that lacks a customerId. This matches RestApiCustomerStateFilter, but worth confirming it's the right behavior for a public, potentially high-traffic GraphQL endpoint.
  4. Cart context is not populated. The foundation ticket mentioned cart context alongside customer context; this PR only populates CustomerState. CartState is left to whatever downstream filters/refreshers handle it. Flag if you want cart context explicitly populated in the interceptor.
  5. SearchQueryResolver swallows exceptions and returns an empty list (logged at WARN). This avoids turning search infrastructure failures into GraphQL errors, but it also hides them from clients. Let me know if you'd prefer these surface through GraphQLExceptionResolver instead.
  6. Dependency exclusion. The reactive-streams exclusion + pin was the minimal change to pass the enforcer. Worth a sanity check that no other module relied on the old 1.0.3 coming in via graphql's transitive path (reactor-core already brings 1.0.4, so this should be a no-op outside graphql).
  7. Per spec, no tests, no DataLoader/BatchMapping optimizations, and no changes to existing REST controllers.

Labels / Milestone

  • Type: Feature
  • Status: ready-for-code-review
  • Milestone: next 7.0.x release

Link to Devin session: https://app.devin.ai/sessions/15e5916b1b97406aae75ee8d5aa99700
Requested by: @Colhodm


Open in Devin Review

Co-Authored-By: Arjun Mishra <arjunsaxmishra@gmail.com>
@devin-ai-integration
Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

devin-ai-integration[bot]

This comment was marked as resolved.

…rror messages

Co-Authored-By: Arjun Mishra <arjunsaxmishra@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

… args

Co-Authored-By: Arjun Mishra <arjunsaxmishra@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

Co-Authored-By: Arjun Mishra <arjunsaxmishra@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…solver

Co-Authored-By: Arjun Mishra <arjunsaxmishra@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…ed search offsets

Co-Authored-By: Arjun Mishra <arjunsaxmishra@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…text to avoid overwriting resolved customer

Co-Authored-By: Arjun Mishra <arjunsaxmishra@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant