Преглед изворни кода

Add documentation about public API and compatability guarantees (#1116)

Motivation:

As we follow SemVer, it's important we declare what our public API is.

Modifications:

Add `docs/api.md` outling our API guarantees and compatability promises
we make for generated code.

Result:

Better docs.
George Barnett пре 4 година
родитељ
комит
15d750f879
1 измењених фајлова са 144 додато и 0 уклоњено
  1. 144 0
      docs/api.md

+ 144 - 0
docs/api.md

@@ -0,0 +1,144 @@
+# gRPC Swift Public API
+
+gRPC Swift follows [Semantic Versioning 2.0.0][semver] (SemVer) which requires
+that projects declare a public API.
+
+For the purpose of this document we consider the gRPC Swift public API to be
+limited to:
+
+1. the `GRPC` module (i.e., code in in [`Sources/GRPC`](../Sources/GRPC)), and
+1. modules generated by the `protoc-gen-grpc-swift` plugin.
+
+Below we cover what consitutes the public API of each, how to use them in an
+acceptable manner, and compatability between `GRPC` and modules generated by
+`protoc-gen-grpc-swift`.
+
+## `GRPC` and Generated Modules
+
+All exported types and methods from the [`GRPC`](../Sources/GRPC) module and those
+generated by `protoc-gen-grpc-swift` are considered public API except for the
+following:
+
+- types which are prefixed with an an underscore (`_`)
+- all methods on types whose name is prefixed with an underscore (`_`)
+- methods which are prefixed with an underscore (`_`)
+
+**Examples**
+
+- `Server.insecure(group:)` **is** part of the public API.
+- `_GRPCClientChannelHandler.channelRead(context:data:)` **is not** part of the
+  public API, the type `_GRPCClientChannelHandler` starts with an underscore.
+- `EmbeddedChannel._configureForEmbeddedServerTest()` **is not** part of the
+  public API, the method starts with an underscore.
+
+### Acceptable Use of the API
+
+#### Conforming Types to Protocols
+
+In gRPC Swift, and more generally Swift, it is only acceptable to conform a type
+to a protocol if you control either the type, the protocol, or both.
+
+- You must not conform any types from `GRPC` or generated code to protocols
+  which you do not own.
+- You must not add conformance to protocols defined by `GRPC` or generated
+  code for types you do not own.
+
+**Examples**
+
+- `extension MyMessageSerializer: MessageSerializer { ... }` is acceptable
+  assuming `MyMessageSerializer` exists in your own codebase.
+- `extension GRPCPayloadSerializer: DebugStringConvertible { ... }` is **not**
+  acceptable, `GRPCPayloadSerializer` is defined in `GRPC` and
+  `DebugStringConvertible` is a standard library protocol.
+
+#### Extending `GRPC` or Generated Types
+
+Extending `GRPC` or generated types with `private` or `internal` methods and
+properties is always allowed.
+
+In order to avoid the potential for clashing names, extending `GRPC` or
+generated types with `public` methods and properties is acceptable if:
+
+- The extension uses a type you own, either as a return type or as a non-default
+  argument.
+- The extension is prefixed with a name which will avoid avoid ambiguity (such
+  as the name of your module).
+
+**Examples**
+
+The following **is not** acceptable since it is public and does not use a type
+owned by the implementer of the extension.
+
+```swift
+extension Server.Builder {
+  public func withSignalHandler(_ handler: @escaping (Int) -> Void) -> Self {
+    ...
+  }
+}
+```
+
+The following **is** acceptable, `MySignal` is defined in the same module as the
+extension and is used as a non-default argument.
+
+```swift
+public struct MySignal {
+  public var signal: Int
+}
+
+extension Server.Builder {
+  public func withSignalHandler(_ handler: @escaping (MySignal) -> Void) -> Self {
+    ...
+  }
+}
+```
+
+The following **is** acceptable because the method is `internal`.
+
+```swift
+extension Server.Builder {
+  internal func withSignalHandler(_ handler: @escaping (Int) -> Void) -> Self {
+    ...
+  }
+}
+```
+
+### Promises the `GRPC` team make
+
+Before releasing a new major version, i.e. gRPC Swift 2.0.0, we promise that:
+
+- None of the public API will be knowingly removed. We will restore any
+  accidental removals as we become aware of them.
+- All additions to the global namespace will be prefixed with `GRPC` or `gRPC`.
+
+We may deprecate APIs before the next major release, however, they will remain
+supported.
+
+**Examples**
+
+- We **might** add a new type called `GRPCChannelPool`
+- We **might** add a new module called `GRPCTestKit`
+- We **might** add a new gloabl function called `gRPCRun`
+- We **will not** add a new type called `ChannelPool`
+- We **will not** add a new module called `TestKit`
+- We **will not** add a new gloabl function called `run`
+
+## Generated Code
+
+gRPC Swift generates code via its `protoc` plugin `protoc-gen-grpc-swift`.
+In order to develop the library over time without breaking existing generated
+code it is important to lay out any API and compatability guarantees.
+
+Before releasing a new major version, i.e. gRPC Swift 2.0.0, we promise that:
+
+- The `GRPC` module will be backward compatible with all code generated by
+  the `protoc-gen-grpc-swift` plugin.
+- Generated code will not have its API broken by being updated.
+
+**Examples**
+
+- Code generated with `protoc-gen-grpc-swift` 1.3.0 will always be compatible
+  with `GRPC` 1.3.0 and higher.
+- Code generated with `protoc-gen-grpc-swift` 1.5.0 offers no compatability
+  guarantees compatible with `GRPC` versions lower than 1.5.0.
+
+[semver]: https://semver.org/spec/v2.0.0.html