@@ -18,6 +18,12 @@ type v1Visitor struct {
1818 Assignments []v1Assignment `json:"assignments"`
1919}
2020
21+ // v4Visitor is the JSON output type for V4 visitor_config endpoints
22+ type v4Visitor struct {
23+ ID string `json:"id"`
24+ Assignments []v4Assignment `json:"assignments"`
25+ }
26+
2127// v1Assignment is the JSON input/output type for V1 visitor endpoints
2228type v1Assignment struct {
2329 SplitName string `json:"split_name"`
@@ -26,6 +32,12 @@ type v1Assignment struct {
2632 Unsynced bool `json:"unsynced"`
2733}
2834
35+ // v4Assignment is the JSON input/output type for V4 visitor_config endpoints
36+ type v4Assignment struct {
37+ SplitName string `json:"split_name"`
38+ Variant string `json:"variant"`
39+ }
40+
2941// v2AssignmentOverrideRequestBody is the JSON input for the V2 assignment override endpoint
3042type v2AssignmentOverrideRequestBody struct {
3143 Assignments []v1Assignment `json:"assignments"`
@@ -44,18 +56,44 @@ type v2VisitorConfig struct {
4456 ExperienceSamplingWeight int `json:"experience_sampling_weight"`
4557}
4658
59+ // v4VisitorConfig is the JSON output type for V4 visitor_config endpoints
60+ type v4VisitorConfig struct {
61+ Splits []v4Split `json:"splits"`
62+ Visitor v4Visitor `json:"visitor"`
63+ ExperienceSamplingWeight int `json:"experience_sampling_weight"`
64+ }
65+
4766// v2SplitRegistry is the JSON output type for V2 split_registry endpoint
4867type v2SplitRegistry struct {
4968 Splits map [string ]* v2Split `json:"splits"`
5069 ExperienceSamplingWeight int `json:"experience_sampling_weight"`
5170}
5271
53- // v2SplitRegistry is the JSON output type for V2 split_registry endpoint
72+ // v4SplitRegistry is the JSON output type for V4 split_registry endpoint
73+ type v4SplitRegistry struct {
74+ Splits []v4Split `json:"splits"`
75+ ExperienceSamplingWeight int `json:"experience_sampling_weight"`
76+ }
77+
78+ // v2Split is the JSON output type for V2 split_registry endpoint
5479type v2Split struct {
5580 Weights map [string ]int `json:"weights"`
5681 FeatureGate bool `json:"feature_gate"`
5782}
5883
84+ // v4Split is the JSON output type for V4 split_registry endpoint
85+ type v4Split struct {
86+ Name string `json:"name"`
87+ Variants []v4Variant `json:"variants"`
88+ FeatureGate bool `json:"feature_gate"`
89+ }
90+
91+ // v4Split is the JSON output type for V4 split_registry endpoint
92+ type v4Variant struct {
93+ Name string `json:"name"`
94+ Weight int `json:"weight"`
95+ }
96+
5997// v1SplitDetail is the JSON output type for the V1 split detail endpoint
6098type v1SplitDetail struct {
6199 Name string `json:"name"`
@@ -126,13 +164,17 @@ func (s *server) routes() {
126164 getV1AppVisitorConfig ,
127165 )
128166 s .handleGet (
129- "/api/v2 /apps/{a}/versions/{v}/builds/{b}/visitors/{id}/config" ,
130- getV2AppVisitorConfig ,
167+ "/api/v4 /apps/{a}/versions/{v}/builds/{b}/visitors/{id}/config" ,
168+ getV4AppVisitorConfig ,
131169 )
132170 s .handleGet (
133171 "/api/v1/apps/{a}/versions/{v}/builds/{b}/identifier_types/{t}/identifiers/{i}/visitor_config" ,
134172 getV1AppVisitorConfig ,
135173 )
174+ s .handleGet (
175+ "/api/v4/apps/{a}/versions/{v}/builds/{b}/identifier_types/{t}/identifiers/{i}/visitor_config" ,
176+ getV4AppVisitorConfig ,
177+ )
136178 s .handleGet (
137179 "/api/v1/split_details/{id}" ,
138180 getV1SplitDetail ,
@@ -141,6 +183,10 @@ func (s *server) routes() {
141183 "/api/v3/builds/{b}/split_registry" ,
142184 getV2PlusSplitRegistry ,
143185 )
186+ s .handleGet (
187+ "/api/v4/builds/{b}/split_registry" ,
188+ getV4SplitRegistry ,
189+ )
144190}
145191
146192func getV1SplitRegistry () (interface {}, error ) {
@@ -181,6 +227,37 @@ func getV2PlusSplitRegistry() (interface{}, error) {
181227 }, nil
182228}
183229
230+ func getV4SplitRegistry () (interface {}, error ) {
231+ schema , err := schema .ReadMerged ()
232+ if err != nil {
233+ return nil , err
234+ }
235+ v4Splits := make ([]v4Split , 0 , len (schema .Splits ))
236+ for _ , split := range schema .Splits {
237+ isFeatureGate := splits .IsFeatureGateFromName (split .Name )
238+ weights , err := splits .WeightsFromYAML (split .Weights )
239+ if err != nil {
240+ return nil , err
241+ }
242+ v4Variants := make ([]v4Variant , 0 , len (* weights ))
243+ for variantName , weight := range * weights {
244+ v4Variants = append (v4Variants , v4Variant {
245+ Name : variantName ,
246+ Weight : weight ,
247+ })
248+ }
249+ v4Splits = append (v4Splits , v4Split {
250+ Name : split .Name ,
251+ Variants : v4Variants ,
252+ FeatureGate : isFeatureGate ,
253+ })
254+ }
255+ return v4SplitRegistry {
256+ Splits : v4Splits ,
257+ ExperienceSamplingWeight : 1 ,
258+ }, nil
259+ }
260+
184261func postNoop (* http.Request ) error {
185262 return nil
186263}
@@ -214,6 +291,24 @@ func getV1Visitor() (interface{}, error) {
214291 }, nil
215292}
216293
294+ func getV4Visitor () (interface {}, error ) {
295+ assignments , err := fakeassignments .Read ()
296+ if err != nil {
297+ return nil , err
298+ }
299+ v4Assignments := make ([]v4Assignment , 0 , len (* assignments ))
300+ for split , variant := range * assignments {
301+ v4Assignments = append (v4Assignments , v4Assignment {
302+ SplitName : split ,
303+ Variant : variant ,
304+ })
305+ }
306+ return v4Visitor {
307+ ID : "00000000-0000-0000-0000-000000000000" ,
308+ Assignments : v4Assignments ,
309+ }, nil
310+ }
311+
217312func getV1VisitorDetail () (interface {}, error ) {
218313 assignments , err := fakeassignments .Read ()
219314 if err != nil {
@@ -312,6 +407,24 @@ func getV1AppVisitorConfig() (interface{}, error) {
312407 }, nil
313408}
314409
410+ func getV4AppVisitorConfig () (interface {}, error ) {
411+ isplitRegistry , err := getV4SplitRegistry ()
412+ splitRegistry := isplitRegistry .(v4SplitRegistry )
413+ if err != nil {
414+ return nil , err
415+ }
416+ ivisitor , err := getV4Visitor ()
417+ visitor := ivisitor .(v4Visitor )
418+ if err != nil {
419+ return nil , err
420+ }
421+ return v4VisitorConfig {
422+ Splits : splitRegistry .Splits ,
423+ Visitor : visitor ,
424+ ExperienceSamplingWeight : splitRegistry .ExperienceSamplingWeight ,
425+ }, nil
426+ }
427+
315428func getV2AppVisitorConfig () (interface {}, error ) {
316429 isplitRegistry , err := getV2PlusSplitRegistry ()
317430 splitRegistry := isplitRegistry .(v2SplitRegistry )
0 commit comments