@@ -30,12 +30,28 @@ type (
30
30
31
31
// APIDefinition defines the global properties of the API.
32
32
APIDefinition struct {
33
+ // APIVersionDefinition contains the default values for properties across all versions.
34
+ * APIVersionDefinition
35
+ // Versions contain the API properties indexed by version.
36
+ Versions map [string ]* APIVersionDefinition
37
+ // Types indexes the user defined types by name.
38
+ Types map [string ]* UserTypeDefinition
39
+ // MediaTypes indexes the API media types by canonical identifier.
40
+ MediaTypes map [string ]* MediaTypeDefinition
41
+ // rand is the random generator used to generate examples.
42
+ rand * RandomGenerator
43
+ }
44
+
45
+ // APIVersionDefinition defines the properties of the API for a given version.
46
+ APIVersionDefinition struct {
33
47
// API name
34
48
Name string
35
49
// API Title
36
50
Title string
37
51
// API description
38
- Description string // API description
52
+ Description string
53
+ // API version if any
54
+ Version string
39
55
// API hostname
40
56
Host string
41
57
// API URL schemes
@@ -64,16 +80,10 @@ type (
64
80
DefaultResponses map [string ]* ResponseDefinition
65
81
// Built-in response templates
66
82
DefaultResponseTemplates map [string ]* ResponseTemplateDefinition
67
- // User types
68
- Types map [string ]* UserTypeDefinition
69
- // Media types
70
- MediaTypes map [string ]* MediaTypeDefinition
71
- // dsl contains the DSL used to create this definition if any.
83
+ // DSL contains the DSL used to create this definition if any.
72
84
DSL func ()
73
- // metadata is a list of key/value pairs
85
+ // Metadata is a list of key/value pairs
74
86
Metadata MetadataDefinition
75
- // rand is the random generator used to generate examples.
76
- rand * RandomGenerator
77
87
}
78
88
79
89
// ContactDefinition contains the API contact information.
@@ -118,7 +128,7 @@ type (
118
128
ParentName string
119
129
// Optional description
120
130
Description string
121
- // Optional version
131
+ // API version that uses this resource.
122
132
Version string
123
133
// Default media type, describes the resource attributes
124
134
MediaType string
@@ -322,6 +332,9 @@ type (
322
332
Names []string
323
333
}
324
334
335
+ // VersionIterator is the type of functions given to IterateVersions.
336
+ VersionIterator func (v * APIVersionDefinition ) error
337
+
325
338
// ResourceIterator is the type of functions given to IterateResources.
326
339
ResourceIterator func (r * ResourceDefinition ) error
327
340
@@ -341,30 +354,11 @@ type (
341
354
// Context returns the generic definition name used in error messages.
342
355
func (a * APIDefinition ) Context () string {
343
356
if a .Name != "" {
344
- return fmt .Sprintf ("api %#v" , a .Name )
357
+ return fmt .Sprintf ("API %#v" , a .Name )
345
358
}
346
359
return "unnamed API"
347
360
}
348
361
349
- // IterateResources calls the given iterator passing in each resource sorted in alphabetical order.
350
- // Iteration stops if an iterator returns an error and in this case IterateResources returns that
351
- // error.
352
- func (a * APIDefinition ) IterateResources (it ResourceIterator ) error {
353
- names := make ([]string , len (a .Resources ))
354
- i := 0
355
- for n := range a .Resources {
356
- names [i ] = n
357
- i ++
358
- }
359
- sort .Strings (names )
360
- for _ , n := range names {
361
- if err := it (a .Resources [n ]); err != nil {
362
- return err
363
- }
364
- }
365
- return nil
366
- }
367
-
368
362
// IterateMediaTypes calls the given iterator passing in each media type sorted in alphabetical order.
369
363
// Iteration stops if an iterator returns an error and in this case IterateMediaTypes returns that
370
364
// error.
@@ -403,25 +397,6 @@ func (a *APIDefinition) IterateUserTypes(it UserTypeIterator) error {
403
397
return nil
404
398
}
405
399
406
- // IterateResponses calls the given iterator passing in each response sorted in alphabetical order.
407
- // Iteration stops if an iterator returns an error and in this case IterateResponses returns that
408
- // error.
409
- func (a * APIDefinition ) IterateResponses (it ResponseIterator ) error {
410
- names := make ([]string , len (a .Responses ))
411
- i := 0
412
- for n := range a .Responses {
413
- names [i ] = n
414
- i ++
415
- }
416
- sort .Strings (names )
417
- for _ , n := range names {
418
- if err := it (a .Responses [n ]); err != nil {
419
- return err
420
- }
421
- }
422
- return nil
423
- }
424
-
425
400
// Example returns a random value for the given data type.
426
401
// If the data type has validations then the example value validates them.
427
402
// Example returns the same random value for a given api name (the random
@@ -449,6 +424,108 @@ func (a *APIDefinition) MediaTypeWithIdentifier(id string) *MediaTypeDefinition
449
424
return mtwi
450
425
}
451
426
427
+ // IterateVersions calls the given iterator passing in each API version definition sorted
428
+ // alphabetically by version name. If the API defines no version then the common version gets
429
+ // passed to the iterator. The common version is the one built with the API DSL function.
430
+ // Iteration stops if an iterator returns an error and in this case IterateVersions returns that
431
+ // error.
432
+ func (a * APIDefinition ) IterateVersions (it VersionIterator ) error {
433
+ if len (a .Versions ) == 0 {
434
+ return it (Design .APIVersionDefinition )
435
+ }
436
+ versions := make ([]string , len (a .Versions ))
437
+ i := 0
438
+ for n := range a .Versions {
439
+ versions [i ] = n
440
+ i ++
441
+ }
442
+ sort .Strings (versions )
443
+ for _ , v := range versions {
444
+ if err := it (Design .Versions [v ]); err != nil {
445
+ return err
446
+ }
447
+ }
448
+ return nil
449
+ }
450
+
451
+ // Context returns the generic definition name used in error messages.
452
+ func (v * APIVersionDefinition ) Context () string {
453
+ if v .Version != "" {
454
+ return fmt .Sprintf ("%s version %s" , Design .Context (), v .Version )
455
+ }
456
+ return Design .Context ()
457
+ }
458
+
459
+ // IsDefault returns true if the version definition applies to all versions (i.e. is the API
460
+ // definition).
461
+ func (v * APIVersionDefinition ) IsDefault () bool {
462
+ return v .Version == ""
463
+ }
464
+
465
+ // IterateResources calls the given iterator passing in each resource sorted in alphabetical order.
466
+ // Iteration stops if an iterator returns an error and in this case IterateResources returns that
467
+ // error.
468
+ func (v * APIVersionDefinition ) IterateResources (it ResourceIterator ) error {
469
+ var allResources map [string ]* ResourceDefinition
470
+ common := Design .APIVersionDefinition
471
+ if common != v {
472
+ allResources = make (map [string ]* ResourceDefinition , len (Design .Resources )+ len (v .Resources ))
473
+ for n , r := range Design .Resources {
474
+ allResources [n ] = r
475
+ }
476
+ for n , r := range v .Resources {
477
+ allResources [n ] = r
478
+ }
479
+ } else {
480
+ allResources = common .Resources
481
+ }
482
+ names := make ([]string , len (allResources ))
483
+ i := 0
484
+ for _ , res := range allResources {
485
+ names [i ] = res .Name
486
+ i ++
487
+ }
488
+ sort .Strings (names )
489
+ for _ , n := range names {
490
+ if err := it (allResources [n ]); err != nil {
491
+ return err
492
+ }
493
+ }
494
+ return nil
495
+ }
496
+
497
+ // IterateResponses calls the given iterator passing in each response sorted in alphabetical order.
498
+ // Iteration stops if an iterator returns an error and in this case IterateResponses returns that
499
+ // error.
500
+ func (v * APIVersionDefinition ) IterateResponses (it ResponseIterator ) error {
501
+ var allResponses map [string ]* ResponseDefinition
502
+ common := Design .APIVersionDefinition
503
+ if common != v {
504
+ allResponses = make (map [string ]* ResponseDefinition , len (Design .Responses )+ len (v .Responses ))
505
+ for n , r := range Design .Responses {
506
+ allResponses [n ] = r
507
+ }
508
+ for n , r := range v .Responses {
509
+ allResponses [n ] = r
510
+ }
511
+ } else {
512
+ allResponses = common .Responses
513
+ }
514
+ names := make ([]string , len (allResponses ))
515
+ i := 0
516
+ for n := range allResponses {
517
+ names [i ] = n
518
+ i ++
519
+ }
520
+ sort .Strings (names )
521
+ for _ , n := range names {
522
+ if err := it (allResponses [n ]); err != nil {
523
+ return err
524
+ }
525
+ }
526
+ return nil
527
+ }
528
+
452
529
// CanonicalIdentifier returns the media type identifier sans suffix
453
530
// which is what the DSL uses to store and lookup media types.
454
531
func CanonicalIdentifier (identifier string ) string {
0 commit comments