github.com/googleapis/api-linter@v1.65.2/docs/rules/0121/no-mutable-cycles.md (about) 1 --- 2 rule: 3 aip: 121 4 name: [core, '0121', no-mutable-cycles] 5 summary: Resources must not form a resource reference cycle. 6 permalink: /121/no-mutable-cycles 7 redirect_from: 8 - /0121/no-mutable-cycles 9 --- 10 11 # Resources must not form a resource reference cycle 12 13 This rule enforces that resources do not create reference cycles of mutable 14 references as mandated in [AIP-121][]. 15 16 ## Details 17 18 This rule scans the fields of every resource and ensures that any references to 19 other resources do not create a mutable cycle between them. 20 21 ## Examples 22 23 **Incorrect** code for this rule: 24 25 ```proto 26 message Book { 27 option (google.api.resource) = { 28 type: "library.googleapis.com/Book" 29 pattern: "books/{book}" 30 }; 31 32 string name = 1; 33 34 // Incorrect. Creates potential reference cycle. 35 string author = 2 [ 36 (google.api.resource_reference).type = "library.googleapis.com/Author" 37 ]; 38 } 39 40 message Author { 41 option (google.api.resource) = { 42 type: "library.googleapis.com/Author" 43 pattern: "authors/{author}" 44 }; 45 46 string name = 1; 47 48 // Incorrect. Creates potential reference cycle. 49 string book = 2 [ 50 (google.api.resource_reference).type = "library.googleapis.com/Book" 51 ]; 52 } 53 ``` 54 55 **Correct** code for this rule: 56 57 ```proto 58 message Book { 59 option (google.api.resource) = { 60 type: "library.googleapis.com/Book" 61 pattern: "books/{book}" 62 }; 63 64 string name = 1; 65 66 // Correct because the other reference is OUTPUT_ONLY. 67 string author = 2 [ 68 (google.api.resource_reference).type = "library.googleapis.com/Author" 69 ]; 70 } 71 72 message Author { 73 option (google.api.resource) = { 74 type: "library.googleapis.com/Author" 75 pattern: "authors/{author}" 76 }; 77 78 string name = 1; 79 80 // Correct because an OUTPUT_ONLY reference breaks the mutation cycle. 81 string book = 2 [ 82 (google.api.resource_reference).type = "library.googleapis.com/Book", 83 (google.api.field_behavior) = OUTPUT_ONLY 84 ]; 85 } 86 ``` 87 88 ## Disabling 89 90 If you need to violate this rule, use a leading comment above the service. 91 Remember to also include an [aip.dev/not-precedent][] comment explaining why. 92 93 ```proto 94 message Book { 95 option (google.api.resource) = { 96 type: "library.googleapis.com/Book" 97 pattern: "books/{book}" 98 }; 99 100 string name = 1; 101 102 // (-- api-linter: core::0121::no-mutable-cycles=disabled 103 // aip.dev/not-precedent: We need to do this because reasons. --) 104 string author = 2 [ 105 (google.api.resource_reference).type = "library.googleapis.com/Author" 106 ]; 107 } 108 109 message Author { 110 option (google.api.resource) = { 111 type: "library.googleapis.com/Author" 112 pattern: "authors/{author}" 113 }; 114 115 string name = 1; 116 117 // (-- api-linter: core::0121::no-mutable-cycles=disabled 118 // aip.dev/not-precedent: We need to do this because reasons. --) 119 string book = 2 [ 120 (google.api.resource_reference).type = "library.googleapis.com/Book" 121 ]; 122 } 123 ``` 124 125 If you need to violate this rule for an entire file, place the comment at the 126 top of the file. 127 128 [aip-121]: https://aip.dev/121 129 [aip.dev/not-precedent]: https://aip.dev/not-precedent