# Google Cloud Storage Swift Client Surface Area Design

This document outlines the design for the Google Cloud Storage Swift client library surface area. The design focuses on client organization, transport protocols, and initialization patterns, drawing comparison with the `google-cloud-rust` storage client.

## 1. Transport Layer

Google Cloud Storage supports multiple transport layers:

- JSON/REST (only v1 API)
- gRPC
- XML (over HTTP)

We opt to use a hybrid approach of JSON/REST and gRPC.

### Decision: Hybrid approach

To align with the official Rust SDK, the control plane (`StorageControl`) will use **gRPC** as the transport layer as the control plane does not support JSON/REST.

File upload protocol will be handled by the veneer client, which will use **JSON/REST** as the transport layer in order to support the resumable file upload protocol.

- **Rationale:** The `google.storage.v2.Storage` gRPC service definition contains both bucket (control) and object (data) operations. By adopting gRPC for both clients, we can wrap the same autogenerated `StorageServiceClient` and avoid maintaining a hybrid model (such as gRPC for folders and REST for objects).
- **Implication:** The Swift generator (`librarian`) and `GoogleCloudGax` must be extended to support gRPC/protobuf code generation and streaming transport. This is assumed to be designed separately.

______________________________________________________________________

## 2. Client Organization

We will only provide a handwritten veneer client for the **data plane (objects)** to wrap the complex resumable upload protocol, and to resume interrupted downloads.

For the **control plane (buckets and folders)**, the API operations are standard and straightforward request-response calls. To minimize handwritten maintenance, these will not have a veneer. Users will interact directly with the generated low-level clients.

- `StorageClient` (Veneer): Dedicated to object data-plane operations (reading, and writing objects).
- `Clients.StorageControl` (Generated): Used directly for some object (delete, list, compute, rewrite) operations, all bucket operations (creation, metadata, IAM), and all folder operations (hierarchical namespace).

```swift
// Example Usage
import GoogleCloudStorage

// Data Plane (Veneer)
let storage = try StorageClient(storageOptions)
// Upload API to-be-designed
let data = try await storage.upload(bucket: "projects/_/buckets/my-bucket", object: "file.txt")

// Control Plane (Directly using low-level generated clients)
let controlClient = try Clients.StorageControl(options)
let bucket = try await controlClient.getBucket(...)
```

### Mapping of Operations and Clients

| Scope | Operations | Client | Type |
| :--- | :--- | :--- | :--- |
| **Data Plane** (Objects) | `readObject`, `writeObject` | `StorageClient` | Handwritten Veneer |
| **Control Plane** (Objects) | `deleteObject`, `getObject`, `listObjects`, `updateObject`, `composeObjects`, `rewriteObjects` | `Clients.StorageServiceClient` | Autogenerated |
| **Control Plane** (Buckets) | `createBucket`, `deleteBucket`, `getBucket`, `listBuckets`, `updateBucket`, `getIamPolicy`, `setIamPolicy` | `Clients.StorageServiceClient` | Autogenerated |
| **Control Plane** (Folders) | `createFolder`, `deleteFolder`, `getFolder`, `listFolders` | `Clients.StorageControlServiceClient` | Autogenerated |

______________________________________________________________________

## 3. Initialization and Configuration

Unlike the Rust SDK which uses a builder pattern, the Swift client will use idiomatic Swift initializers backed by a categorized configuration struct.

### Decision: Categorized `StorageClientOptions`

While low-level autogenerated control-plane clients will continue to accept standard `GoogleCloudGax.ClientOptions`, the handwritten veneer client (`StorageClient`) requires rich domain configuration (e.g., project ID overrides, upload thresholds, default retry policies).

To prevent a flat "junk drawer" of dozens of mixed parameters, we introduce `StorageClientOptions` as a conceptual categorized configuration object. For example, we can provide additional configuration for uploads:

```swift
/// High-level conceptual shape of the veneer configuration
public struct StorageClientOptions: Sendable {
    /// Standard GAX networking and auth options
    public var client: ClientOptions

    /// Explicit Cloud Project ID override
    public var projectId: String?

    /// Default configuration inherited by data-plane operations (e.g., Uploads)
    public var upload: UploadOptions

    public init() {}

    /// Chaining configuration helper matching project idioms
    public func with(_ config: (inout Self) throws -> Void) rethrows -> Self {
        var copy = self
        try config(&copy)
        return copy
    }
}
```

```swift
// Configuration using `.with` chaining
let storageOptions = StorageClientOptions().with {
    $0.client.credentials = ...
    $0.upload.validation = .md5
}

// Initialization
let storage = try StorageClient(storageOptions)
```

______________________________________________________________________

## 4. Code Organization and Namespaces

All Google Cloud Storage functionality—including the handwritten veneer client and the autogenerated control plane clients—will be consolidated into a single installable Swift package.

### Unified Package

- **Package Path:** `packages/storage`
- **Package Name:** `GoogleCloudStorage`
- **Namespace/Module:** `GoogleCloudStorage`

Both the handwritten veneer and the autogenerated code will compile into the same `GoogleCloudStorage` module. This simplifies the developer experience, requiring only a single import statement to access the entire GCS feature set.

### Directory Layout

```
google-cloud-swift/
└── packages/
    └── storage/
        ├── Package.swift
        └── Sources/
            └── GoogleCloudStorage/
                ├── StorageClient.swift            # Handwritten veneer (data plane)
                ├── Generated/                     # Autogenerated GCS API code
                │   ├── Storage.swift       # Generated from google/storage/v2
                │   ├── StorageControl.swift# Generated from google/storage/control/v2
                │   └── ...
                └── ...
```

### Wrapper Architecture

- `StorageClient` will wrap the object-related methods of the generated `Storage` internal code to provide a high-level, idiomatic Swift API (handling streams, retry loops, upload tasks, etc.).
- There will be no wrapper client for the control plane. Users will interact directly with the autogenerated `Clients.Storage` and `Clients.StorageControl` which are exposed publicly from the same `GoogleCloudStorage` module.

### Namespace and Imports

- **User Imports:** Users only need to import `GoogleCloudStorage`.

```swift
import GoogleCloudStorage

// Data Plane (Veneer) - initialized with categorized options
let storage = try StorageClient(storageOptions)
let data = try await storage.readObject(bucket: "my-bucket", object: "file.txt")

// Control Plane (Directly using public generated clients from same module)
let control = try Clients.StorageControl(options)
let folder = try await control.getFolder(...)
```
