Create separate GraphQL type, resolver and interface for Group.dependencies
Context
Currently, Project.dependencies and Group.dependencies both share the same GraphQL type (and hence resolver).
In this discussion: #513524 (comment 2417628391) it was decided to create a new, separate type for the Group.dependencies (DependencyAggregation).
Since both the Dependency- and DependencyAggreation-type share data, and to DRY up the FE Queries, we can introduce an interface type and share some of the data.
classDiagram
%% Interface
class DependencyEntityType {
<<interface>>
+id: GlobalIDType
+name: String
+version: String
+packager: PackageManagerEnum
+location: LocationType
+licenses: [LicenseType]
+reachability: ReachabilityEnum
+vulnerability_count: Int
}
%% Concrete Types
class DependencyType {
+implements DependencyEntityType
+authorize :read_dependency
}
class DependencyAggregationType {
+implements DependencyEntityType
+occurrence_count: Int
}
%% Relationships
DependencyEntityType <|.. DependencyType
DependencyEntityType <|.. DependencyAggregationType
%% Used in
class ProjectType {
+dependencies: DependencyType.connection_type
}
class GroupType {
+dependencies: DependencyAggregationType.connection_type
}
ProjectType --> DependencyType : exposes
GroupType --> DependencyAggregationType : exposes
See this POC for details: !186099
Note: This will allow us to create a query like the below example:
query GetDependencies($fullPath: ID!, $first: Int = 20) {
namespace(fullPath: $fullPath) {
id
name
# This will work for both project and group namespaces
dependencies(first: $first) {
pageInfo {
hasNextPage
endCursor
}
nodes {
...DependencyFields
# Fields specific to DependencyAggregationType (only available for groups)
... on DependencyAggregation {
occurrenceCount
}
}
}
}
}
# Common fields defined by the DependencyEntityType interface
fragment DependencyFields on DependencyEntity {
id
name
version
packager
location {
path
lineNumber
}
licenses {
name
url
}
reachability
vulnerabilityCount
}
Implementation Details
GraphQL Types:
- Create
DependencyEntityTypeinterface with all common fields between group and project level - Keep the existing
DependencyTypefor project dependencies and refer toDependencyEntityType - Create DependencyAggregationType for group dependencies with the
occurrence_countfield
Resolvers:
- Split existing Resolvers::Sbom::DependenciesResolver into:
- Update for individual dependencies (project context)
- Create new for aggregated dependencies (group context)
Tests
- Update
ee/spec/graphql/types/sbom/dependency_type_spec.rb - Create specs for DependencyEntityType interface
- Create specs for DependencyAggregationType
Edited by Charlie Kroon