You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@iceberg.apache.org by GitBox <gi...@apache.org> on 2021/12/08 09:20:28 UTC

[GitHub] [iceberg] laurentgo commented on a change in pull request #3561: [CORE] Specification for an HTTP REST catalog

laurentgo commented on a change in pull request #3561:
URL: https://github.com/apache/iceberg/pull/3561#discussion_r764644950



##########
File path: rest_docs/rest-catalog-open-api-v0.1.yaml
##########
@@ -0,0 +1,633 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+---
+openapi: 3.0.3
+info:
+  title: Apache Iceberg REST Catalog API
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: 1.0.0
+  description:
+    Defines the specification for the first version of the REST Catalog API. Implementations should support both Iceberg table specs v1 and v2, with priority given to v2.
+servers:
+  - url: https://{host}:{port}/{basePath}
+    variables:
+      host:
+        description: The host address for the specified server
+        default: localhost
+      port:
+        description: The port used when addressing the host
+        default: "443"
+      basePath:
+        default: v1
+  - url: http://127.0.0.1:1080/v1
+    description: URL Used for Mock-Server Unit Tests
+# All routes are currently configured using an Authorization header.
+security:
+  - BearerAuth: []
+paths:
+  /config:
+    get:
+      tags:
+        - Configuration API
+      summary: List all catalog configuration settings
+      operationId: getConfig
+      description:
+        All REST catalog clients will first call this route to get some configuration provided by the server.
+        This route will return any server specified default configuration values for the catalog, such as
+        configuration values used to setup the catalog for usage with Spark (e.g. vectorization-enabled).
+
+        Users should be able to override these values with client specified values.
+
+        The server might be able to request that the client use its value over a value that has been
+        configured in the client application. How and if it will do that is an open question, and thus
+        not currently specified in this documents schema.
+      responses:
+        default:
+          description: Server-Specific Configuration Values (or Overrides)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/IcebergConfiguration'
+        "400":
+          description: Unknown Error
+        "401":
+          description: Unauthorized
+  /namespaces:
+    get:
+      tags:
+        - Catalog API
+      summary: List namespaces, optionally providing a parent namespace to list underneaath
+      description:
+        List all namespaces at a certain level, optionally starting from a given parent namespace.
+        For example, if table a.b.t exists, using 'SELECT NAMESPACE IN a' this would translate into
+        `GET /namespaces?parent=a` and must return Namepace.of("a","b").
+      operationId: listNamespaces
+      parameters:
+        - name: parent
+          in: query
+          description: Optional parent namespace under which to list namespaces. When empty, list top-level namespaces.
+          required: false
+          schema:
+            type: string
+          example: ?parent=accounting.tax
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListNamespacesResponse'
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found (Parent namespace does not exist)
+    post:
+      tags:
+        - Catalog API
+      summary: Create a namespace
+      description: Create a namespace, with an optional set of properties. The server might also add properties, such as last_modified_time etc.
+      operationId: createNamespace
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateNamespaceRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '409':
+          $ref: '#/components/responses/NamespaceAlreadyExistsResponse'
+
+  /namespaces/{namespace}:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    get:
+      tags:
+        - Catalog API
+      summary: Load the metadata properties for a namespace
+      operationId: loadNamespaceMetadata
+      description: Return all stored metadata properties for a given namespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/GetNamespaceResponse'
+        '404':
+          $ref: '#/components/responses/NoSuchNamespaceResponse'
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a namespace exists
+      operationId: namespaceExists
+      description: Check if a namespace exists.
+      responses:
+        '200':
+          description: OK - Namesapce exists
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a namespace from the catalog. Namespace must be empty.
+      operationId: dropNamespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example: { "data": { "dropped": true } }

Review comment:
       Looking at the semantic of the API, maybe a body is not necessary and can be substituted with 2 different status:
   - `204: No Content` is DELETE was successful
   - `409: Conflict` if the DELETE was not done because the object was not empty
   
   It is also clear based on the status code if the operation was successful or not...

##########
File path: rest_docs/rest-catalog-open-api-v0.1.yaml
##########
@@ -0,0 +1,633 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+---
+openapi: 3.0.3
+info:
+  title: Apache Iceberg REST Catalog API
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: 1.0.0
+  description:
+    Defines the specification for the first version of the REST Catalog API. Implementations should support both Iceberg table specs v1 and v2, with priority given to v2.
+servers:
+  - url: https://{host}:{port}/{basePath}
+    variables:
+      host:
+        description: The host address for the specified server
+        default: localhost
+      port:
+        description: The port used when addressing the host
+        default: "443"
+      basePath:
+        default: v1
+  - url: http://127.0.0.1:1080/v1
+    description: URL Used for Mock-Server Unit Tests
+# All routes are currently configured using an Authorization header.
+security:
+  - BearerAuth: []
+paths:
+  /config:
+    get:
+      tags:
+        - Configuration API
+      summary: List all catalog configuration settings
+      operationId: getConfig
+      description:
+        All REST catalog clients will first call this route to get some configuration provided by the server.
+        This route will return any server specified default configuration values for the catalog, such as
+        configuration values used to setup the catalog for usage with Spark (e.g. vectorization-enabled).
+
+        Users should be able to override these values with client specified values.
+
+        The server might be able to request that the client use its value over a value that has been
+        configured in the client application. How and if it will do that is an open question, and thus
+        not currently specified in this documents schema.
+      responses:
+        default:
+          description: Server-Specific Configuration Values (or Overrides)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/IcebergConfiguration'
+        "400":
+          description: Unknown Error
+        "401":
+          description: Unauthorized
+  /namespaces:
+    get:
+      tags:
+        - Catalog API
+      summary: List namespaces, optionally providing a parent namespace to list underneaath
+      description:
+        List all namespaces at a certain level, optionally starting from a given parent namespace.
+        For example, if table a.b.t exists, using 'SELECT NAMESPACE IN a' this would translate into
+        `GET /namespaces?parent=a` and must return Namepace.of("a","b").
+      operationId: listNamespaces
+      parameters:
+        - name: parent
+          in: query
+          description: Optional parent namespace under which to list namespaces. When empty, list top-level namespaces.
+          required: false
+          schema:
+            type: string
+          example: ?parent=accounting.tax
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListNamespacesResponse'
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found (Parent namespace does not exist)
+    post:
+      tags:
+        - Catalog API
+      summary: Create a namespace
+      description: Create a namespace, with an optional set of properties. The server might also add properties, such as last_modified_time etc.
+      operationId: createNamespace
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateNamespaceRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '409':
+          $ref: '#/components/responses/NamespaceAlreadyExistsResponse'
+
+  /namespaces/{namespace}:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    get:
+      tags:
+        - Catalog API
+      summary: Load the metadata properties for a namespace
+      operationId: loadNamespaceMetadata
+      description: Return all stored metadata properties for a given namespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/GetNamespaceResponse'
+        '404':
+          $ref: '#/components/responses/NoSuchNamespaceResponse'
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a namespace exists
+      operationId: namespaceExists
+      description: Check if a namespace exists.
+      responses:
+        '200':
+          description: OK - Namesapce exists

Review comment:
       Typo: `Namespace exists`

##########
File path: rest_docs/rest-catalog-open-api-v0.1.yaml
##########
@@ -0,0 +1,657 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+---
+openapi: 3.0.3
+info:
+  title: Apache Iceberg REST Catalog API
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: 1.0.0
+  description:
+    Defines the specification for the first version of the REST Catalog API. Implementations should support both Iceberg table specs v1 and v2, with priority given to v2.
+servers:
+  - url: https://{host}:{port}/{basePath}
+    variables:
+      host:
+        description: The host address for the specified server
+        default: localhost
+      port:
+        description: The port used when addressing the host
+        default: "443"
+      basePath:
+        default: v1
+  - url: http://127.0.0.1:1080/v1
+    description: URL Used for Mock-Server Unit Tests
+# All routes are currently configured using an Authorization header.
+security:
+  - BearerAuth: []
+paths:
+  /config:
+    get:
+      tags:
+        - Configuration API
+      summary: List all catalog configuration settings
+      operationId: getConfig
+      description: >
+        All REST catalog clients will first call this route to get possible catalog-specific
+        configuration values provided by the server, that the catalog (and its HTTP client)
+        can use to complete the `initialize` step.
+
+        This call is similar to the initial set-up calls that some catalogs already do for
+        domain-specific information, such as the Nessie catalog or the Glue catalog.
+        This is to allow for services that would like to integrate with Iceberg to do so,
+        and to be able to add their own domain-specific information into the REST catalog without
+        requiring them to write and distribute a catalog themselves.
+
+        There will be two sets of values provided -
+
+        - overrides
+          * An object containing values that the client must use.
+            For example, auth headers that the client will receive from the server
+            as temporary credentials.
+        - defaults
+          * Catalog-specific configuration that the client may use as a default value.
+            These are optional and the client is free to use its own value for these.
+
+      responses:
+        default:
+          description: Server-Specific Configuration Values (or Overrides)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/IcebergConfiguration'
+              example: {
+                "data": {
+                  "overrides": {
+                    "prefix": "/raul",
+                    "headers": {
+                      "User-Agent": "Raul",
+                      "Authorization": "Basic Ym9zY236Ym9zY28=",
+                    }
+                  },
+                  "defaults": {
+                    "clients": 5,
+                    "headers": {
+                      "Upgrade-Insecure-Requests": "1"
+                    }
+                  }
+                }
+              }
+        "400":
+          description: Unknown Error
+        "401":
+          description: Unauthorized
+  /namespaces:
+    get:
+      tags:
+        - Catalog API
+      summary: List namespaces, optionally providing a parent namespace to list underneaath
+      description:
+        List all namespaces at a certain level, optionally starting from a given parent namespace.
+        For example, if table a.b.t exists, using 'SELECT NAMESPACE IN a' this would translate into
+        `GET /namespaces?parent=a` and must return Namepace.of("a","b").
+      operationId: listNamespaces
+      parameters:
+        - name: parent
+          in: query
+          description: Optional parent namespace under which to list namespaces. When empty, list top-level namespaces.
+          required: false
+          schema:
+            type: string
+          example: ?parent=accounting.tax
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListNamespacesResponse'
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found (Parent namespace does not exist)
+    post:
+      tags:
+        - Catalog API
+      summary: Create a namespace
+      description: Create a namespace, with an optional set of properties. The server might also add properties, such as last_modified_time etc.
+      operationId: createNamespace
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateNamespaceRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '409':
+          $ref: '#/components/responses/NamespaceAlreadyExistsResponse'
+
+  /namespaces/{namespace}:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    get:
+      tags:
+        - Catalog API
+      summary: Load the metadata properties for a namespace
+      operationId: loadNamespaceMetadata
+      description: Return all stored metadata properties for a given namespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/GetNamespaceResponse'
+        '404':
+          $ref: '#/components/responses/NoSuchNamespaceResponse'
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a namespace exists
+      operationId: namespaceExists
+      description: Check if a namespace exists.
+      responses:
+        '200':
+          description: OK - Namesapce exists
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a namespace from the catalog. Namespace must be empty.
+      operationId: dropNamespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example: { "data": { "dropped": true } }
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+
+
+  /namespaces/{namespace}/properties:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    post:
+      tags:
+        - Catalog API
+      summary: Set or remove properties on a namespace
+      operationId: setProperties / removeProperties
+      description:
+        Set and/or remove a collection or properties on a namespae.
+        The request body specifies a list of properties to remove and a map
+        of key value pairs to update.
+
+        Properties that are not in the request are not modified or removed by this call.
+        Server implementations are not required to support namespace properties.
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/UpdatePropertiesRequest'
+            example:
+              { "toRemove": [ "foo", "bar" ], "toUpdate": { "owner": "Raoul" } }
+        required: true
+      responses:
+        200:
+          description: OK
+          content:
+            'application/json':
+              schema:
+                # This is an IcebergResponseObject<SetPropertiesResponse>, in that it uses the standard wrapper of { "data": toJson(SetPropertiesResponse) }
+                $ref: '#/components/schemas/UpdatePropertiesResponse'
+              example: {
+                "data": {
+                  "updated": [ "owner" ],
+                  "removed": [ "foo" ],
+                  "notPresent": [ "bar" ]
+                }
+              }
+        404:
+          description: Not Found (NoSuchNamespaceException)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example:
+                { "error": { "message": "Namespace does not exist", "type": "NoSuchNamespaceException", "code": 404 } }
+        406:
+          description: Not Acceptable (Unsupported Operation)
+        422:
+          description: Unprocessable Entity. A property key was included in both toRemove and toUpdate.
+
+  /namespaces/{namespace}/tables:
+    parameters:
+      - name: namespace
+        description: A namespace identifier under which to list tables
+        in: path
+        required: true
+        schema:
+          type: string
+        examples:
+          singlepart_namespace:
+            value: "accounting"
+          multipart_namespace:
+            value: "accounting.tax"
+    get:
+      tags:
+        - Catalog API
+      summary: List all table identifiers underneath a given namespace
+      description: Return all table identifiers under this namespace
+      operationId: listTables
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListTablesResponse'
+        '404':
+          description: Not Found (NoSuchNamespaceException)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example:
+                '{ error: { message: "Namespace does not exist", type: "NoSuchNamespaceException", code: 404 }'
+
+  /namespaces/{namespace}/tables/{table}:
+    parameters:
+      - name: namespace
+        in: path
+        description: A namespace identifier
+        required: true
+        schema:
+          type: string
+        examples:
+          singlepart_namespace:
+            value: "accounting"
+          multipart_namespace:
+            value: "accounting.tax"
+      - name: table
+        in: path
+        description: A table name
+        required: true
+        schema:
+          type: string
+        example: "sales"
+
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a table from the catalog
+      operationId: dropTable
+      description: Remove a table from the catalog
+      parameters:
+        - name: purgeRequested
+          in: query
+          required: false
+          description: Whether the user requested to purge the underlying table's data and metadata
+          schema:
+            type: boolean
+            default: false
+      responses:
+        200:
+          description: OK
+          content:
+            'application/json':
+              schema:
+                $ref: '#/components/schemas/DropTableResponse'
+              example: { "data": { "dropped": true, "purged": false } }
+        202:
+          # TODO - Add a callback or handle to check on the state of an async purge request
+          description: Accepted - for use if purgeRequested is implemented as an asynchronous action.
+        404:
+          $ref: '#/components/responses/NoSuchTableResponse'
+
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a table exists
+      operationId: tableExists
+      description:
+        Check if a table exists within a given namespace.
+      responses:
+        200:
+          description: OK - Table Exists
+        401:
+          description: Unauthorized
+        404:
+          description: Not Found
+
+  /tables/rename:
+    post:
+      tags:
+        - Catalog API
+      summary: Rename a table from its current name to a new name
+      description:
+        Rename a table from one identifier to another. It's valid to move a table
+        across namespaces, but the server implementation doesn't need to support it.
+      operationId: renameTable
+      requestBody:
+        description: Current table identifier to rename and new table identifier to rename to
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/RenameTableRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '404':
+          description:
+            Not Found
+            - NoSuchTableException, Table to rename does not exist
+            - NoSuchNamespaceException, The target namespace of the new table identifier does not exist
+          content:
+            application/json:
+              schema:
+                oneOf:
+                  - $ref: '#/components/responses/NoSuchTableResponse'
+                  - $ref: '#/components/responses/NoSuchNamespaceResponse'
+              examples:
+                table_to_rename_does_not_exist:
+                  value: {
+                    "error": {
+                      "message": "Table to rename does not exist",
+                      "type": "NoSuchTableException",
+                      "code": 404
+                    } }
+                namespace_to_rename_to_does_not_exist:
+                  value: {
+                    "error": {
+                      "message": "Namespace to rename to does not exist",
+                      "type": "NoSuchNameSpaceException",
+                      "code": 404
+                    } }
+        '406':
+          description: Not Acceptable (UnsupportedOperationException)
+        '409':
+          description: Conflict (AlreadyExistsException - The new target table identifier already exists)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/TableAlreadyExistsError'
+              example: {
+                "error": {
+                  "message": "Table already exists",
+                  "type": "AlreadyExistsException",
+                  "code": 409
+                } }
+
+components:
+
+  ##############################
+  # Application Schema Objects #
+  ##############################
+  schemas:
+    ResponseDataObject:
+      type: object
+      description: JSON data payload returned in a successful response body
+      properties:
+        data:
+          type: object
+          description: Wrapper for the response of a successful request
+      example: { "data": { "identifiers": [ "office.employees", "office.dogs", "office.cats" ] } }
+    ResponseErrorObject:
+      type: object
+      description: JSON error payload returned in a response with further details on the error
+      required:
+        - message
+        - type
+        - code
+      properties:
+        message:
+          type: string
+          description: Human-readable error message
+        type:
+          type: string
+          description: Internal type of the error, such as an exception class

Review comment:
       should an exception class be used? wouldn't that be implementation specific?

##########
File path: rest_docs/rest-catalog-open-api-v0.1.yaml
##########
@@ -0,0 +1,657 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+---
+openapi: 3.0.3
+info:
+  title: Apache Iceberg REST Catalog API
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: 1.0.0
+  description:
+    Defines the specification for the first version of the REST Catalog API. Implementations should support both Iceberg table specs v1 and v2, with priority given to v2.
+servers:
+  - url: https://{host}:{port}/{basePath}
+    variables:
+      host:
+        description: The host address for the specified server
+        default: localhost
+      port:
+        description: The port used when addressing the host
+        default: "443"
+      basePath:
+        default: v1
+  - url: http://127.0.0.1:1080/v1
+    description: URL Used for Mock-Server Unit Tests
+# All routes are currently configured using an Authorization header.
+security:
+  - BearerAuth: []
+paths:
+  /config:
+    get:
+      tags:
+        - Configuration API
+      summary: List all catalog configuration settings
+      operationId: getConfig
+      description: >
+        All REST catalog clients will first call this route to get possible catalog-specific
+        configuration values provided by the server, that the catalog (and its HTTP client)
+        can use to complete the `initialize` step.
+
+        This call is similar to the initial set-up calls that some catalogs already do for
+        domain-specific information, such as the Nessie catalog or the Glue catalog.
+        This is to allow for services that would like to integrate with Iceberg to do so,
+        and to be able to add their own domain-specific information into the REST catalog without
+        requiring them to write and distribute a catalog themselves.
+
+        There will be two sets of values provided -
+
+        - overrides
+          * An object containing values that the client must use.
+            For example, auth headers that the client will receive from the server
+            as temporary credentials.
+        - defaults
+          * Catalog-specific configuration that the client may use as a default value.
+            These are optional and the client is free to use its own value for these.
+
+      responses:
+        default:
+          description: Server-Specific Configuration Values (or Overrides)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/IcebergConfiguration'
+              example: {
+                "data": {
+                  "overrides": {
+                    "prefix": "/raul",
+                    "headers": {
+                      "User-Agent": "Raul",
+                      "Authorization": "Basic Ym9zY236Ym9zY28=",
+                    }
+                  },
+                  "defaults": {
+                    "clients": 5,
+                    "headers": {
+                      "Upgrade-Insecure-Requests": "1"
+                    }
+                  }
+                }
+              }
+        "400":
+          description: Unknown Error
+        "401":
+          description: Unauthorized
+  /namespaces:
+    get:
+      tags:
+        - Catalog API
+      summary: List namespaces, optionally providing a parent namespace to list underneaath
+      description:
+        List all namespaces at a certain level, optionally starting from a given parent namespace.
+        For example, if table a.b.t exists, using 'SELECT NAMESPACE IN a' this would translate into
+        `GET /namespaces?parent=a` and must return Namepace.of("a","b").
+      operationId: listNamespaces
+      parameters:
+        - name: parent
+          in: query
+          description: Optional parent namespace under which to list namespaces. When empty, list top-level namespaces.
+          required: false
+          schema:
+            type: string
+          example: ?parent=accounting.tax
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListNamespacesResponse'
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found (Parent namespace does not exist)
+    post:
+      tags:
+        - Catalog API
+      summary: Create a namespace
+      description: Create a namespace, with an optional set of properties. The server might also add properties, such as last_modified_time etc.
+      operationId: createNamespace
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateNamespaceRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '409':
+          $ref: '#/components/responses/NamespaceAlreadyExistsResponse'
+
+  /namespaces/{namespace}:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    get:
+      tags:
+        - Catalog API
+      summary: Load the metadata properties for a namespace
+      operationId: loadNamespaceMetadata
+      description: Return all stored metadata properties for a given namespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/GetNamespaceResponse'
+        '404':
+          $ref: '#/components/responses/NoSuchNamespaceResponse'
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a namespace exists
+      operationId: namespaceExists
+      description: Check if a namespace exists.
+      responses:
+        '200':
+          description: OK - Namesapce exists
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a namespace from the catalog. Namespace must be empty.
+      operationId: dropNamespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example: { "data": { "dropped": true } }
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+
+
+  /namespaces/{namespace}/properties:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    post:
+      tags:
+        - Catalog API
+      summary: Set or remove properties on a namespace
+      operationId: setProperties / removeProperties
+      description:
+        Set and/or remove a collection or properties on a namespae.
+        The request body specifies a list of properties to remove and a map
+        of key value pairs to update.
+
+        Properties that are not in the request are not modified or removed by this call.
+        Server implementations are not required to support namespace properties.
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/UpdatePropertiesRequest'
+            example:
+              { "toRemove": [ "foo", "bar" ], "toUpdate": { "owner": "Raoul" } }
+        required: true
+      responses:
+        200:
+          description: OK
+          content:
+            'application/json':
+              schema:
+                # This is an IcebergResponseObject<SetPropertiesResponse>, in that it uses the standard wrapper of { "data": toJson(SetPropertiesResponse) }
+                $ref: '#/components/schemas/UpdatePropertiesResponse'
+              example: {
+                "data": {
+                  "updated": [ "owner" ],
+                  "removed": [ "foo" ],
+                  "notPresent": [ "bar" ]
+                }
+              }
+        404:
+          description: Not Found (NoSuchNamespaceException)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example:
+                { "error": { "message": "Namespace does not exist", "type": "NoSuchNamespaceException", "code": 404 } }
+        406:
+          description: Not Acceptable (Unsupported Operation)
+        422:
+          description: Unprocessable Entity. A property key was included in both toRemove and toUpdate.
+
+  /namespaces/{namespace}/tables:
+    parameters:
+      - name: namespace
+        description: A namespace identifier under which to list tables
+        in: path
+        required: true
+        schema:
+          type: string
+        examples:
+          singlepart_namespace:
+            value: "accounting"
+          multipart_namespace:
+            value: "accounting.tax"
+    get:
+      tags:
+        - Catalog API
+      summary: List all table identifiers underneath a given namespace
+      description: Return all table identifiers under this namespace
+      operationId: listTables
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListTablesResponse'
+        '404':
+          description: Not Found (NoSuchNamespaceException)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example:
+                '{ error: { message: "Namespace does not exist", type: "NoSuchNamespaceException", code: 404 }'
+
+  /namespaces/{namespace}/tables/{table}:
+    parameters:
+      - name: namespace
+        in: path
+        description: A namespace identifier
+        required: true
+        schema:
+          type: string
+        examples:
+          singlepart_namespace:
+            value: "accounting"
+          multipart_namespace:
+            value: "accounting.tax"
+      - name: table
+        in: path
+        description: A table name
+        required: true
+        schema:
+          type: string
+        example: "sales"
+
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a table from the catalog
+      operationId: dropTable
+      description: Remove a table from the catalog
+      parameters:
+        - name: purgeRequested
+          in: query
+          required: false
+          description: Whether the user requested to purge the underlying table's data and metadata
+          schema:
+            type: boolean

Review comment:
       (nit) maybe avoid boolean and use some enum value so that we may be able to extend with different purge policy?

##########
File path: rest_docs/rest-catalog-open-api-v0.1.yaml
##########
@@ -0,0 +1,657 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+---
+openapi: 3.0.3
+info:
+  title: Apache Iceberg REST Catalog API
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: 1.0.0
+  description:
+    Defines the specification for the first version of the REST Catalog API. Implementations should support both Iceberg table specs v1 and v2, with priority given to v2.
+servers:
+  - url: https://{host}:{port}/{basePath}
+    variables:
+      host:
+        description: The host address for the specified server
+        default: localhost
+      port:
+        description: The port used when addressing the host
+        default: "443"
+      basePath:
+        default: v1
+  - url: http://127.0.0.1:1080/v1
+    description: URL Used for Mock-Server Unit Tests
+# All routes are currently configured using an Authorization header.
+security:
+  - BearerAuth: []
+paths:
+  /config:
+    get:
+      tags:
+        - Configuration API
+      summary: List all catalog configuration settings
+      operationId: getConfig
+      description: >
+        All REST catalog clients will first call this route to get possible catalog-specific
+        configuration values provided by the server, that the catalog (and its HTTP client)
+        can use to complete the `initialize` step.
+
+        This call is similar to the initial set-up calls that some catalogs already do for
+        domain-specific information, such as the Nessie catalog or the Glue catalog.
+        This is to allow for services that would like to integrate with Iceberg to do so,
+        and to be able to add their own domain-specific information into the REST catalog without
+        requiring them to write and distribute a catalog themselves.
+
+        There will be two sets of values provided -
+
+        - overrides
+          * An object containing values that the client must use.
+            For example, auth headers that the client will receive from the server
+            as temporary credentials.
+        - defaults
+          * Catalog-specific configuration that the client may use as a default value.
+            These are optional and the client is free to use its own value for these.
+
+      responses:
+        default:
+          description: Server-Specific Configuration Values (or Overrides)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/IcebergConfiguration'
+              example: {
+                "data": {
+                  "overrides": {
+                    "prefix": "/raul",
+                    "headers": {
+                      "User-Agent": "Raul",
+                      "Authorization": "Basic Ym9zY236Ym9zY28=",
+                    }
+                  },
+                  "defaults": {
+                    "clients": 5,
+                    "headers": {
+                      "Upgrade-Insecure-Requests": "1"
+                    }
+                  }
+                }
+              }
+        "400":
+          description: Unknown Error
+        "401":
+          description: Unauthorized
+  /namespaces:
+    get:
+      tags:
+        - Catalog API
+      summary: List namespaces, optionally providing a parent namespace to list underneaath
+      description:
+        List all namespaces at a certain level, optionally starting from a given parent namespace.
+        For example, if table a.b.t exists, using 'SELECT NAMESPACE IN a' this would translate into
+        `GET /namespaces?parent=a` and must return Namepace.of("a","b").
+      operationId: listNamespaces
+      parameters:
+        - name: parent
+          in: query
+          description: Optional parent namespace under which to list namespaces. When empty, list top-level namespaces.
+          required: false
+          schema:
+            type: string
+          example: ?parent=accounting.tax
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListNamespacesResponse'
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found (Parent namespace does not exist)
+    post:
+      tags:
+        - Catalog API
+      summary: Create a namespace
+      description: Create a namespace, with an optional set of properties. The server might also add properties, such as last_modified_time etc.
+      operationId: createNamespace
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateNamespaceRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '409':
+          $ref: '#/components/responses/NamespaceAlreadyExistsResponse'
+
+  /namespaces/{namespace}:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    get:
+      tags:
+        - Catalog API
+      summary: Load the metadata properties for a namespace
+      operationId: loadNamespaceMetadata
+      description: Return all stored metadata properties for a given namespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/GetNamespaceResponse'
+        '404':
+          $ref: '#/components/responses/NoSuchNamespaceResponse'
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a namespace exists
+      operationId: namespaceExists
+      description: Check if a namespace exists.
+      responses:
+        '200':
+          description: OK - Namesapce exists
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a namespace from the catalog. Namespace must be empty.
+      operationId: dropNamespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example: { "data": { "dropped": true } }
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+
+
+  /namespaces/{namespace}/properties:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    post:
+      tags:
+        - Catalog API
+      summary: Set or remove properties on a namespace
+      operationId: setProperties / removeProperties
+      description:
+        Set and/or remove a collection or properties on a namespae.
+        The request body specifies a list of properties to remove and a map
+        of key value pairs to update.
+
+        Properties that are not in the request are not modified or removed by this call.
+        Server implementations are not required to support namespace properties.
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/UpdatePropertiesRequest'
+            example:
+              { "toRemove": [ "foo", "bar" ], "toUpdate": { "owner": "Raoul" } }
+        required: true
+      responses:
+        200:
+          description: OK
+          content:
+            'application/json':
+              schema:
+                # This is an IcebergResponseObject<SetPropertiesResponse>, in that it uses the standard wrapper of { "data": toJson(SetPropertiesResponse) }
+                $ref: '#/components/schemas/UpdatePropertiesResponse'
+              example: {
+                "data": {
+                  "updated": [ "owner" ],
+                  "removed": [ "foo" ],
+                  "notPresent": [ "bar" ]
+                }
+              }
+        404:
+          description: Not Found (NoSuchNamespaceException)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example:
+                { "error": { "message": "Namespace does not exist", "type": "NoSuchNamespaceException", "code": 404 } }
+        406:
+          description: Not Acceptable (Unsupported Operation)
+        422:
+          description: Unprocessable Entity. A property key was included in both toRemove and toUpdate.
+
+  /namespaces/{namespace}/tables:
+    parameters:
+      - name: namespace
+        description: A namespace identifier under which to list tables
+        in: path
+        required: true
+        schema:
+          type: string
+        examples:
+          singlepart_namespace:
+            value: "accounting"
+          multipart_namespace:
+            value: "accounting.tax"
+    get:
+      tags:
+        - Catalog API
+      summary: List all table identifiers underneath a given namespace
+      description: Return all table identifiers under this namespace
+      operationId: listTables
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListTablesResponse'
+        '404':
+          description: Not Found (NoSuchNamespaceException)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example:
+                '{ error: { message: "Namespace does not exist", type: "NoSuchNamespaceException", code: 404 }'
+
+  /namespaces/{namespace}/tables/{table}:
+    parameters:
+      - name: namespace
+        in: path
+        description: A namespace identifier
+        required: true
+        schema:
+          type: string
+        examples:
+          singlepart_namespace:
+            value: "accounting"
+          multipart_namespace:
+            value: "accounting.tax"
+      - name: table
+        in: path
+        description: A table name
+        required: true
+        schema:
+          type: string
+        example: "sales"
+
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a table from the catalog
+      operationId: dropTable
+      description: Remove a table from the catalog
+      parameters:
+        - name: purgeRequested
+          in: query
+          required: false
+          description: Whether the user requested to purge the underlying table's data and metadata
+          schema:
+            type: boolean
+            default: false
+      responses:
+        200:
+          description: OK
+          content:
+            'application/json':
+              schema:
+                $ref: '#/components/schemas/DropTableResponse'
+              example: { "data": { "dropped": true, "purged": false } }
+        202:
+          # TODO - Add a callback or handle to check on the state of an async purge request
+          description: Accepted - for use if purgeRequested is implemented as an asynchronous action.
+        404:
+          $ref: '#/components/responses/NoSuchTableResponse'
+
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a table exists
+      operationId: tableExists
+      description:
+        Check if a table exists within a given namespace.
+      responses:
+        200:
+          description: OK - Table Exists
+        401:
+          description: Unauthorized
+        404:
+          description: Not Found
+
+  /tables/rename:
+    post:
+      tags:
+        - Catalog API
+      summary: Rename a table from its current name to a new name
+      description:
+        Rename a table from one identifier to another. It's valid to move a table
+        across namespaces, but the server implementation doesn't need to support it.
+      operationId: renameTable
+      requestBody:
+        description: Current table identifier to rename and new table identifier to rename to
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/RenameTableRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '404':
+          description:
+            Not Found
+            - NoSuchTableException, Table to rename does not exist
+            - NoSuchNamespaceException, The target namespace of the new table identifier does not exist
+          content:
+            application/json:
+              schema:
+                oneOf:
+                  - $ref: '#/components/responses/NoSuchTableResponse'
+                  - $ref: '#/components/responses/NoSuchNamespaceResponse'
+              examples:
+                table_to_rename_does_not_exist:
+                  value: {
+                    "error": {
+                      "message": "Table to rename does not exist",
+                      "type": "NoSuchTableException",
+                      "code": 404
+                    } }
+                namespace_to_rename_to_does_not_exist:
+                  value: {
+                    "error": {
+                      "message": "Namespace to rename to does not exist",
+                      "type": "NoSuchNameSpaceException",
+                      "code": 404
+                    } }
+        '406':
+          description: Not Acceptable (UnsupportedOperationException)
+        '409':
+          description: Conflict (AlreadyExistsException - The new target table identifier already exists)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/TableAlreadyExistsError'
+              example: {
+                "error": {
+                  "message": "Table already exists",
+                  "type": "AlreadyExistsException",
+                  "code": 409
+                } }
+
+components:
+
+  ##############################
+  # Application Schema Objects #
+  ##############################
+  schemas:
+    ResponseDataObject:
+      type: object
+      description: JSON data payload returned in a successful response body
+      properties:
+        data:
+          type: object
+          description: Wrapper for the response of a successful request
+      example: { "data": { "identifiers": [ "office.employees", "office.dogs", "office.cats" ] } }
+    ResponseErrorObject:
+      type: object
+      description: JSON error payload returned in a response with further details on the error
+      required:
+        - message
+        - type
+        - code
+      properties:
+        message:
+          type: string
+          description: Human-readable error message
+        type:
+          type: string
+          description: Internal type of the error, such as an exception class
+          example: NoSuchNamespaceException
+        code:
+          type: integer
+          minimum: 100
+          maximum: 600
+          description: HTTP response code
+          example: 404
+    TableIdentifier:
+      type: object
+      required:
+        - namespace
+      properties:
+        namespace:
+          type: array
+          description: Individual levels of the namespace
+          items:
+            type: string
+          nullable: false
+        name:
+          type: string
+          nullable: false
+    CreateNamespaceRequest:
+      type: object
+      required:
+        - namespace
+      properties:
+        namespace:
+          type: array
+          description: Individual levels of the namespace
+          items:
+            type: string
+        properties:

Review comment:
       For the sake of interoperability, wouldn't it be better to have something more prescriptive than just a dictionary of properties?

##########
File path: rest_docs/rest-catalog-open-api-v0.1.yaml
##########
@@ -0,0 +1,633 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+---
+openapi: 3.0.3
+info:
+  title: Apache Iceberg REST Catalog API
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: 1.0.0
+  description:
+    Defines the specification for the first version of the REST Catalog API. Implementations should support both Iceberg table specs v1 and v2, with priority given to v2.
+servers:
+  - url: https://{host}:{port}/{basePath}
+    variables:
+      host:
+        description: The host address for the specified server
+        default: localhost
+      port:
+        description: The port used when addressing the host
+        default: "443"
+      basePath:
+        default: v1
+  - url: http://127.0.0.1:1080/v1
+    description: URL Used for Mock-Server Unit Tests
+# All routes are currently configured using an Authorization header.
+security:
+  - BearerAuth: []
+paths:
+  /config:
+    get:
+      tags:
+        - Configuration API
+      summary: List all catalog configuration settings
+      operationId: getConfig
+      description:
+        All REST catalog clients will first call this route to get some configuration provided by the server.
+        This route will return any server specified default configuration values for the catalog, such as
+        configuration values used to setup the catalog for usage with Spark (e.g. vectorization-enabled).
+
+        Users should be able to override these values with client specified values.
+
+        The server might be able to request that the client use its value over a value that has been
+        configured in the client application. How and if it will do that is an open question, and thus
+        not currently specified in this documents schema.
+      responses:
+        default:
+          description: Server-Specific Configuration Values (or Overrides)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/IcebergConfiguration'
+        "400":
+          description: Unknown Error
+        "401":
+          description: Unauthorized
+  /namespaces:
+    get:
+      tags:
+        - Catalog API
+      summary: List namespaces, optionally providing a parent namespace to list underneaath
+      description:
+        List all namespaces at a certain level, optionally starting from a given parent namespace.
+        For example, if table a.b.t exists, using 'SELECT NAMESPACE IN a' this would translate into
+        `GET /namespaces?parent=a` and must return Namepace.of("a","b").

Review comment:
       typo: `must return Namespace.of("a", "b")`

##########
File path: rest_docs/rest-catalog-open-api-v0.1.yaml
##########
@@ -0,0 +1,633 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+---
+openapi: 3.0.3
+info:
+  title: Apache Iceberg REST Catalog API
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: 1.0.0
+  description:
+    Defines the specification for the first version of the REST Catalog API. Implementations should support both Iceberg table specs v1 and v2, with priority given to v2.
+servers:
+  - url: https://{host}:{port}/{basePath}
+    variables:
+      host:
+        description: The host address for the specified server
+        default: localhost
+      port:
+        description: The port used when addressing the host
+        default: "443"
+      basePath:
+        default: v1
+  - url: http://127.0.0.1:1080/v1
+    description: URL Used for Mock-Server Unit Tests
+# All routes are currently configured using an Authorization header.
+security:
+  - BearerAuth: []
+paths:
+  /config:
+    get:
+      tags:
+        - Configuration API
+      summary: List all catalog configuration settings
+      operationId: getConfig
+      description:
+        All REST catalog clients will first call this route to get some configuration provided by the server.
+        This route will return any server specified default configuration values for the catalog, such as
+        configuration values used to setup the catalog for usage with Spark (e.g. vectorization-enabled).
+
+        Users should be able to override these values with client specified values.
+
+        The server might be able to request that the client use its value over a value that has been
+        configured in the client application. How and if it will do that is an open question, and thus
+        not currently specified in this documents schema.
+      responses:
+        default:
+          description: Server-Specific Configuration Values (or Overrides)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/IcebergConfiguration'
+        "400":
+          description: Unknown Error
+        "401":
+          description: Unauthorized
+  /namespaces:
+    get:
+      tags:
+        - Catalog API
+      summary: List namespaces, optionally providing a parent namespace to list underneaath
+      description:
+        List all namespaces at a certain level, optionally starting from a given parent namespace.
+        For example, if table a.b.t exists, using 'SELECT NAMESPACE IN a' this would translate into
+        `GET /namespaces?parent=a` and must return Namepace.of("a","b").
+      operationId: listNamespaces
+      parameters:
+        - name: parent
+          in: query
+          description: Optional parent namespace under which to list namespaces. When empty, list top-level namespaces.
+          required: false
+          schema:
+            type: string
+          example: ?parent=accounting.tax
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListNamespacesResponse'
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found (Parent namespace does not exist)
+    post:
+      tags:
+        - Catalog API
+      summary: Create a namespace
+      description: Create a namespace, with an optional set of properties. The server might also add properties, such as last_modified_time etc.
+      operationId: createNamespace
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateNamespaceRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '409':
+          $ref: '#/components/responses/NamespaceAlreadyExistsResponse'
+
+  /namespaces/{namespace}:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    get:
+      tags:
+        - Catalog API
+      summary: Load the metadata properties for a namespace
+      operationId: loadNamespaceMetadata
+      description: Return all stored metadata properties for a given namespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/GetNamespaceResponse'
+        '404':
+          $ref: '#/components/responses/NoSuchNamespaceResponse'
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a namespace exists
+      operationId: namespaceExists
+      description: Check if a namespace exists.
+      responses:
+        '200':
+          description: OK - Namesapce exists
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a namespace from the catalog. Namespace must be empty.
+      operationId: dropNamespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example: { "data": { "dropped": true } }
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+
+
+  /namespaces/{namespace}/properties:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    post:

Review comment:
       Why not using PATCH on path `/namespaces/{namespace}` since that method would correspond to that definition (note that there are also rfc proposal for json patch format: https://datatracker.ietf.org/doc/html/rfc6902 and https://datatracker.ietf.org/doc/html/rfc7386)

##########
File path: rest_docs/rest-catalog-open-api-v0.1.yaml
##########
@@ -0,0 +1,657 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+---
+openapi: 3.0.3
+info:
+  title: Apache Iceberg REST Catalog API
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: 1.0.0
+  description:
+    Defines the specification for the first version of the REST Catalog API. Implementations should support both Iceberg table specs v1 and v2, with priority given to v2.
+servers:
+  - url: https://{host}:{port}/{basePath}
+    variables:
+      host:
+        description: The host address for the specified server
+        default: localhost
+      port:
+        description: The port used when addressing the host
+        default: "443"
+      basePath:
+        default: v1
+  - url: http://127.0.0.1:1080/v1
+    description: URL Used for Mock-Server Unit Tests
+# All routes are currently configured using an Authorization header.
+security:
+  - BearerAuth: []
+paths:
+  /config:
+    get:
+      tags:
+        - Configuration API
+      summary: List all catalog configuration settings
+      operationId: getConfig
+      description: >
+        All REST catalog clients will first call this route to get possible catalog-specific
+        configuration values provided by the server, that the catalog (and its HTTP client)
+        can use to complete the `initialize` step.
+
+        This call is similar to the initial set-up calls that some catalogs already do for
+        domain-specific information, such as the Nessie catalog or the Glue catalog.
+        This is to allow for services that would like to integrate with Iceberg to do so,
+        and to be able to add their own domain-specific information into the REST catalog without
+        requiring them to write and distribute a catalog themselves.
+
+        There will be two sets of values provided -
+
+        - overrides
+          * An object containing values that the client must use.
+            For example, auth headers that the client will receive from the server
+            as temporary credentials.
+        - defaults
+          * Catalog-specific configuration that the client may use as a default value.
+            These are optional and the client is free to use its own value for these.
+
+      responses:
+        default:
+          description: Server-Specific Configuration Values (or Overrides)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/IcebergConfiguration'
+              example: {
+                "data": {
+                  "overrides": {
+                    "prefix": "/raul",
+                    "headers": {
+                      "User-Agent": "Raul",
+                      "Authorization": "Basic Ym9zY236Ym9zY28=",
+                    }
+                  },
+                  "defaults": {
+                    "clients": 5,
+                    "headers": {
+                      "Upgrade-Insecure-Requests": "1"
+                    }
+                  }
+                }
+              }
+        "400":
+          description: Unknown Error
+        "401":
+          description: Unauthorized
+  /namespaces:
+    get:
+      tags:
+        - Catalog API
+      summary: List namespaces, optionally providing a parent namespace to list underneaath
+      description:
+        List all namespaces at a certain level, optionally starting from a given parent namespace.
+        For example, if table a.b.t exists, using 'SELECT NAMESPACE IN a' this would translate into
+        `GET /namespaces?parent=a` and must return Namepace.of("a","b").
+      operationId: listNamespaces
+      parameters:
+        - name: parent
+          in: query
+          description: Optional parent namespace under which to list namespaces. When empty, list top-level namespaces.
+          required: false
+          schema:
+            type: string
+          example: ?parent=accounting.tax
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListNamespacesResponse'
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found (Parent namespace does not exist)
+    post:
+      tags:
+        - Catalog API
+      summary: Create a namespace
+      description: Create a namespace, with an optional set of properties. The server might also add properties, such as last_modified_time etc.
+      operationId: createNamespace
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateNamespaceRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '409':
+          $ref: '#/components/responses/NamespaceAlreadyExistsResponse'
+
+  /namespaces/{namespace}:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    get:
+      tags:
+        - Catalog API
+      summary: Load the metadata properties for a namespace
+      operationId: loadNamespaceMetadata
+      description: Return all stored metadata properties for a given namespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/GetNamespaceResponse'
+        '404':
+          $ref: '#/components/responses/NoSuchNamespaceResponse'
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a namespace exists
+      operationId: namespaceExists
+      description: Check if a namespace exists.
+      responses:
+        '200':
+          description: OK - Namesapce exists
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a namespace from the catalog. Namespace must be empty.
+      operationId: dropNamespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example: { "data": { "dropped": true } }
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+
+
+  /namespaces/{namespace}/properties:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    post:
+      tags:
+        - Catalog API
+      summary: Set or remove properties on a namespace
+      operationId: setProperties / removeProperties
+      description:

Review comment:
       Is there a way to detect/prevent concurrent modifications if needed?

##########
File path: rest_docs/rest-catalog-open-api-v0.1.yaml
##########
@@ -0,0 +1,657 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+---
+openapi: 3.0.3
+info:
+  title: Apache Iceberg REST Catalog API
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: 1.0.0
+  description:
+    Defines the specification for the first version of the REST Catalog API. Implementations should support both Iceberg table specs v1 and v2, with priority given to v2.
+servers:
+  - url: https://{host}:{port}/{basePath}
+    variables:
+      host:
+        description: The host address for the specified server
+        default: localhost
+      port:
+        description: The port used when addressing the host
+        default: "443"
+      basePath:
+        default: v1
+  - url: http://127.0.0.1:1080/v1
+    description: URL Used for Mock-Server Unit Tests
+# All routes are currently configured using an Authorization header.
+security:
+  - BearerAuth: []
+paths:
+  /config:
+    get:
+      tags:
+        - Configuration API
+      summary: List all catalog configuration settings
+      operationId: getConfig
+      description: >
+        All REST catalog clients will first call this route to get possible catalog-specific
+        configuration values provided by the server, that the catalog (and its HTTP client)
+        can use to complete the `initialize` step.
+
+        This call is similar to the initial set-up calls that some catalogs already do for
+        domain-specific information, such as the Nessie catalog or the Glue catalog.
+        This is to allow for services that would like to integrate with Iceberg to do so,
+        and to be able to add their own domain-specific information into the REST catalog without
+        requiring them to write and distribute a catalog themselves.
+
+        There will be two sets of values provided -
+
+        - overrides
+          * An object containing values that the client must use.
+            For example, auth headers that the client will receive from the server
+            as temporary credentials.
+        - defaults
+          * Catalog-specific configuration that the client may use as a default value.
+            These are optional and the client is free to use its own value for these.
+
+      responses:
+        default:
+          description: Server-Specific Configuration Values (or Overrides)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/IcebergConfiguration'
+              example: {
+                "data": {
+                  "overrides": {
+                    "prefix": "/raul",
+                    "headers": {
+                      "User-Agent": "Raul",
+                      "Authorization": "Basic Ym9zY236Ym9zY28=",

Review comment:
       I hope this is not an actual set of credentials? I'm kind of concern about a server config endpoint returning a security header tbh...

##########
File path: rest_docs/rest-catalog-open-api-v0.1.yaml
##########
@@ -0,0 +1,657 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+---
+openapi: 3.0.3
+info:
+  title: Apache Iceberg REST Catalog API
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: 1.0.0
+  description:
+    Defines the specification for the first version of the REST Catalog API. Implementations should support both Iceberg table specs v1 and v2, with priority given to v2.
+servers:
+  - url: https://{host}:{port}/{basePath}
+    variables:
+      host:
+        description: The host address for the specified server
+        default: localhost
+      port:
+        description: The port used when addressing the host
+        default: "443"
+      basePath:
+        default: v1
+  - url: http://127.0.0.1:1080/v1
+    description: URL Used for Mock-Server Unit Tests
+# All routes are currently configured using an Authorization header.
+security:
+  - BearerAuth: []
+paths:
+  /config:
+    get:
+      tags:
+        - Configuration API
+      summary: List all catalog configuration settings
+      operationId: getConfig
+      description: >
+        All REST catalog clients will first call this route to get possible catalog-specific
+        configuration values provided by the server, that the catalog (and its HTTP client)
+        can use to complete the `initialize` step.
+
+        This call is similar to the initial set-up calls that some catalogs already do for
+        domain-specific information, such as the Nessie catalog or the Glue catalog.
+        This is to allow for services that would like to integrate with Iceberg to do so,
+        and to be able to add their own domain-specific information into the REST catalog without
+        requiring them to write and distribute a catalog themselves.
+
+        There will be two sets of values provided -
+
+        - overrides
+          * An object containing values that the client must use.
+            For example, auth headers that the client will receive from the server
+            as temporary credentials.
+        - defaults
+          * Catalog-specific configuration that the client may use as a default value.
+            These are optional and the client is free to use its own value for these.
+
+      responses:
+        default:
+          description: Server-Specific Configuration Values (or Overrides)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/IcebergConfiguration'
+              example: {
+                "data": {
+                  "overrides": {
+                    "prefix": "/raul",
+                    "headers": {
+                      "User-Agent": "Raul",
+                      "Authorization": "Basic Ym9zY236Ym9zY28=",
+                    }
+                  },
+                  "defaults": {
+                    "clients": 5,
+                    "headers": {
+                      "Upgrade-Insecure-Requests": "1"
+                    }
+                  }
+                }
+              }
+        "400":
+          description: Unknown Error
+        "401":
+          description: Unauthorized
+  /namespaces:
+    get:
+      tags:
+        - Catalog API
+      summary: List namespaces, optionally providing a parent namespace to list underneaath
+      description:
+        List all namespaces at a certain level, optionally starting from a given parent namespace.
+        For example, if table a.b.t exists, using 'SELECT NAMESPACE IN a' this would translate into
+        `GET /namespaces?parent=a` and must return Namepace.of("a","b").
+      operationId: listNamespaces
+      parameters:
+        - name: parent
+          in: query
+          description: Optional parent namespace under which to list namespaces. When empty, list top-level namespaces.
+          required: false
+          schema:
+            type: string
+          example: ?parent=accounting.tax
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListNamespacesResponse'
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found (Parent namespace does not exist)
+    post:
+      tags:
+        - Catalog API
+      summary: Create a namespace
+      description: Create a namespace, with an optional set of properties. The server might also add properties, such as last_modified_time etc.
+      operationId: createNamespace
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateNamespaceRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '409':
+          $ref: '#/components/responses/NamespaceAlreadyExistsResponse'
+
+  /namespaces/{namespace}:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    get:
+      tags:
+        - Catalog API
+      summary: Load the metadata properties for a namespace
+      operationId: loadNamespaceMetadata
+      description: Return all stored metadata properties for a given namespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/GetNamespaceResponse'
+        '404':
+          $ref: '#/components/responses/NoSuchNamespaceResponse'
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a namespace exists
+      operationId: namespaceExists
+      description: Check if a namespace exists.
+      responses:
+        '200':
+          description: OK - Namesapce exists
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a namespace from the catalog. Namespace must be empty.
+      operationId: dropNamespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example: { "data": { "dropped": true } }
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+
+
+  /namespaces/{namespace}/properties:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    post:
+      tags:
+        - Catalog API
+      summary: Set or remove properties on a namespace
+      operationId: setProperties / removeProperties
+      description:
+        Set and/or remove a collection or properties on a namespae.
+        The request body specifies a list of properties to remove and a map
+        of key value pairs to update.
+
+        Properties that are not in the request are not modified or removed by this call.
+        Server implementations are not required to support namespace properties.
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/UpdatePropertiesRequest'
+            example:
+              { "toRemove": [ "foo", "bar" ], "toUpdate": { "owner": "Raoul" } }
+        required: true
+      responses:
+        200:
+          description: OK
+          content:
+            'application/json':
+              schema:
+                # This is an IcebergResponseObject<SetPropertiesResponse>, in that it uses the standard wrapper of { "data": toJson(SetPropertiesResponse) }
+                $ref: '#/components/schemas/UpdatePropertiesResponse'
+              example: {
+                "data": {
+                  "updated": [ "owner" ],
+                  "removed": [ "foo" ],
+                  "notPresent": [ "bar" ]
+                }
+              }
+        404:
+          description: Not Found (NoSuchNamespaceException)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example:
+                { "error": { "message": "Namespace does not exist", "type": "NoSuchNamespaceException", "code": 404 } }
+        406:
+          description: Not Acceptable (Unsupported Operation)
+        422:
+          description: Unprocessable Entity. A property key was included in both toRemove and toUpdate.
+
+  /namespaces/{namespace}/tables:
+    parameters:
+      - name: namespace
+        description: A namespace identifier under which to list tables
+        in: path
+        required: true
+        schema:
+          type: string
+        examples:
+          singlepart_namespace:
+            value: "accounting"
+          multipart_namespace:
+            value: "accounting.tax"
+    get:
+      tags:
+        - Catalog API
+      summary: List all table identifiers underneath a given namespace
+      description: Return all table identifiers under this namespace
+      operationId: listTables
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListTablesResponse'
+        '404':
+          description: Not Found (NoSuchNamespaceException)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example:
+                '{ error: { message: "Namespace does not exist", type: "NoSuchNamespaceException", code: 404 }'
+
+  /namespaces/{namespace}/tables/{table}:
+    parameters:
+      - name: namespace
+        in: path
+        description: A namespace identifier
+        required: true
+        schema:
+          type: string
+        examples:
+          singlepart_namespace:
+            value: "accounting"
+          multipart_namespace:
+            value: "accounting.tax"
+      - name: table
+        in: path
+        description: A table name
+        required: true
+        schema:
+          type: string
+        example: "sales"
+
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a table from the catalog
+      operationId: dropTable
+      description: Remove a table from the catalog
+      parameters:
+        - name: purgeRequested
+          in: query
+          required: false
+          description: Whether the user requested to purge the underlying table's data and metadata
+          schema:
+            type: boolean
+            default: false
+      responses:
+        200:
+          description: OK
+          content:
+            'application/json':
+              schema:
+                $ref: '#/components/schemas/DropTableResponse'
+              example: { "data": { "dropped": true, "purged": false } }
+        202:
+          # TODO - Add a callback or handle to check on the state of an async purge request
+          description: Accepted - for use if purgeRequested is implemented as an asynchronous action.
+        404:
+          $ref: '#/components/responses/NoSuchTableResponse'
+
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a table exists
+      operationId: tableExists
+      description:
+        Check if a table exists within a given namespace.
+      responses:
+        200:
+          description: OK - Table Exists
+        401:
+          description: Unauthorized
+        404:
+          description: Not Found
+
+  /tables/rename:

Review comment:
       Why not keeping a RESTFul approach and make it a method of the original table?

##########
File path: rest_docs/rest-catalog-open-api-v0.1.yaml
##########
@@ -0,0 +1,657 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+---
+openapi: 3.0.3
+info:
+  title: Apache Iceberg REST Catalog API
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: 1.0.0
+  description:
+    Defines the specification for the first version of the REST Catalog API. Implementations should support both Iceberg table specs v1 and v2, with priority given to v2.
+servers:
+  - url: https://{host}:{port}/{basePath}
+    variables:
+      host:
+        description: The host address for the specified server
+        default: localhost
+      port:
+        description: The port used when addressing the host
+        default: "443"
+      basePath:
+        default: v1
+  - url: http://127.0.0.1:1080/v1
+    description: URL Used for Mock-Server Unit Tests
+# All routes are currently configured using an Authorization header.
+security:
+  - BearerAuth: []
+paths:
+  /config:
+    get:
+      tags:
+        - Configuration API
+      summary: List all catalog configuration settings
+      operationId: getConfig
+      description: >
+        All REST catalog clients will first call this route to get possible catalog-specific
+        configuration values provided by the server, that the catalog (and its HTTP client)
+        can use to complete the `initialize` step.
+
+        This call is similar to the initial set-up calls that some catalogs already do for
+        domain-specific information, such as the Nessie catalog or the Glue catalog.
+        This is to allow for services that would like to integrate with Iceberg to do so,
+        and to be able to add their own domain-specific information into the REST catalog without
+        requiring them to write and distribute a catalog themselves.
+
+        There will be two sets of values provided -
+
+        - overrides
+          * An object containing values that the client must use.
+            For example, auth headers that the client will receive from the server
+            as temporary credentials.
+        - defaults
+          * Catalog-specific configuration that the client may use as a default value.
+            These are optional and the client is free to use its own value for these.
+
+      responses:
+        default:
+          description: Server-Specific Configuration Values (or Overrides)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/IcebergConfiguration'
+              example: {
+                "data": {
+                  "overrides": {
+                    "prefix": "/raul",
+                    "headers": {
+                      "User-Agent": "Raul",
+                      "Authorization": "Basic Ym9zY236Ym9zY28=",
+                    }
+                  },
+                  "defaults": {
+                    "clients": 5,
+                    "headers": {
+                      "Upgrade-Insecure-Requests": "1"
+                    }
+                  }
+                }
+              }
+        "400":
+          description: Unknown Error
+        "401":
+          description: Unauthorized
+  /namespaces:
+    get:
+      tags:
+        - Catalog API
+      summary: List namespaces, optionally providing a parent namespace to list underneaath
+      description:
+        List all namespaces at a certain level, optionally starting from a given parent namespace.
+        For example, if table a.b.t exists, using 'SELECT NAMESPACE IN a' this would translate into
+        `GET /namespaces?parent=a` and must return Namepace.of("a","b").
+      operationId: listNamespaces
+      parameters:
+        - name: parent
+          in: query
+          description: Optional parent namespace under which to list namespaces. When empty, list top-level namespaces.
+          required: false
+          schema:
+            type: string
+          example: ?parent=accounting.tax
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListNamespacesResponse'
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found (Parent namespace does not exist)
+    post:
+      tags:
+        - Catalog API
+      summary: Create a namespace
+      description: Create a namespace, with an optional set of properties. The server might also add properties, such as last_modified_time etc.
+      operationId: createNamespace
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateNamespaceRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '409':
+          $ref: '#/components/responses/NamespaceAlreadyExistsResponse'
+
+  /namespaces/{namespace}:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    get:
+      tags:
+        - Catalog API
+      summary: Load the metadata properties for a namespace
+      operationId: loadNamespaceMetadata
+      description: Return all stored metadata properties for a given namespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/GetNamespaceResponse'
+        '404':
+          $ref: '#/components/responses/NoSuchNamespaceResponse'
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a namespace exists
+      operationId: namespaceExists
+      description: Check if a namespace exists.
+      responses:
+        '200':
+          description: OK - Namesapce exists
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a namespace from the catalog. Namespace must be empty.
+      operationId: dropNamespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example: { "data": { "dropped": true } }
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+
+
+  /namespaces/{namespace}/properties:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    post:
+      tags:
+        - Catalog API
+      summary: Set or remove properties on a namespace
+      operationId: setProperties / removeProperties
+      description:
+        Set and/or remove a collection or properties on a namespae.
+        The request body specifies a list of properties to remove and a map
+        of key value pairs to update.
+
+        Properties that are not in the request are not modified or removed by this call.
+        Server implementations are not required to support namespace properties.
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/UpdatePropertiesRequest'
+            example:
+              { "toRemove": [ "foo", "bar" ], "toUpdate": { "owner": "Raoul" } }
+        required: true
+      responses:
+        200:
+          description: OK
+          content:
+            'application/json':
+              schema:
+                # This is an IcebergResponseObject<SetPropertiesResponse>, in that it uses the standard wrapper of { "data": toJson(SetPropertiesResponse) }
+                $ref: '#/components/schemas/UpdatePropertiesResponse'
+              example: {
+                "data": {
+                  "updated": [ "owner" ],
+                  "removed": [ "foo" ],
+                  "notPresent": [ "bar" ]
+                }
+              }
+        404:
+          description: Not Found (NoSuchNamespaceException)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example:
+                { "error": { "message": "Namespace does not exist", "type": "NoSuchNamespaceException", "code": 404 } }
+        406:
+          description: Not Acceptable (Unsupported Operation)
+        422:
+          description: Unprocessable Entity. A property key was included in both toRemove and toUpdate.
+
+  /namespaces/{namespace}/tables:
+    parameters:
+      - name: namespace
+        description: A namespace identifier under which to list tables
+        in: path
+        required: true
+        schema:
+          type: string
+        examples:
+          singlepart_namespace:
+            value: "accounting"
+          multipart_namespace:
+            value: "accounting.tax"
+    get:
+      tags:
+        - Catalog API
+      summary: List all table identifiers underneath a given namespace
+      description: Return all table identifiers under this namespace
+      operationId: listTables
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListTablesResponse'
+        '404':
+          description: Not Found (NoSuchNamespaceException)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example:
+                '{ error: { message: "Namespace does not exist", type: "NoSuchNamespaceException", code: 404 }'
+
+  /namespaces/{namespace}/tables/{table}:
+    parameters:
+      - name: namespace
+        in: path
+        description: A namespace identifier
+        required: true
+        schema:
+          type: string
+        examples:
+          singlepart_namespace:
+            value: "accounting"
+          multipart_namespace:
+            value: "accounting.tax"
+      - name: table
+        in: path
+        description: A table name
+        required: true
+        schema:
+          type: string
+        example: "sales"
+
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a table from the catalog
+      operationId: dropTable
+      description: Remove a table from the catalog
+      parameters:
+        - name: purgeRequested
+          in: query
+          required: false
+          description: Whether the user requested to purge the underlying table's data and metadata
+          schema:
+            type: boolean
+            default: false
+      responses:
+        200:
+          description: OK
+          content:
+            'application/json':
+              schema:
+                $ref: '#/components/schemas/DropTableResponse'
+              example: { "data": { "dropped": true, "purged": false } }
+        202:
+          # TODO - Add a callback or handle to check on the state of an async purge request
+          description: Accepted - for use if purgeRequested is implemented as an asynchronous action.
+        404:
+          $ref: '#/components/responses/NoSuchTableResponse'
+
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a table exists
+      operationId: tableExists
+      description:
+        Check if a table exists within a given namespace.
+      responses:
+        200:
+          description: OK - Table Exists
+        401:
+          description: Unauthorized
+        404:
+          description: Not Found
+
+  /tables/rename:
+    post:
+      tags:
+        - Catalog API
+      summary: Rename a table from its current name to a new name
+      description:
+        Rename a table from one identifier to another. It's valid to move a table
+        across namespaces, but the server implementation doesn't need to support it.
+      operationId: renameTable
+      requestBody:
+        description: Current table identifier to rename and new table identifier to rename to
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/RenameTableRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '404':
+          description:
+            Not Found
+            - NoSuchTableException, Table to rename does not exist
+            - NoSuchNamespaceException, The target namespace of the new table identifier does not exist
+          content:
+            application/json:
+              schema:
+                oneOf:

Review comment:
       since 200 is returned, does it mean there should be a response body in case of success too?

##########
File path: rest_docs/rest-catalog-open-api-v0.1.yaml
##########
@@ -0,0 +1,633 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+---
+openapi: 3.0.3
+info:
+  title: Apache Iceberg REST Catalog API
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: 1.0.0
+  description:
+    Defines the specification for the first version of the REST Catalog API. Implementations should support both Iceberg table specs v1 and v2, with priority given to v2.
+servers:
+  - url: https://{host}:{port}/{basePath}
+    variables:
+      host:
+        description: The host address for the specified server
+        default: localhost
+      port:
+        description: The port used when addressing the host
+        default: "443"
+      basePath:
+        default: v1
+  - url: http://127.0.0.1:1080/v1
+    description: URL Used for Mock-Server Unit Tests
+# All routes are currently configured using an Authorization header.
+security:
+  - BearerAuth: []
+paths:
+  /config:
+    get:
+      tags:
+        - Configuration API
+      summary: List all catalog configuration settings
+      operationId: getConfig
+      description:
+        All REST catalog clients will first call this route to get some configuration provided by the server.
+        This route will return any server specified default configuration values for the catalog, such as
+        configuration values used to setup the catalog for usage with Spark (e.g. vectorization-enabled).
+
+        Users should be able to override these values with client specified values.
+
+        The server might be able to request that the client use its value over a value that has been
+        configured in the client application. How and if it will do that is an open question, and thus
+        not currently specified in this documents schema.
+      responses:
+        default:
+          description: Server-Specific Configuration Values (or Overrides)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/IcebergConfiguration'
+        "400":
+          description: Unknown Error
+        "401":
+          description: Unauthorized
+  /namespaces:
+    get:
+      tags:
+        - Catalog API
+      summary: List namespaces, optionally providing a parent namespace to list underneaath
+      description:
+        List all namespaces at a certain level, optionally starting from a given parent namespace.
+        For example, if table a.b.t exists, using 'SELECT NAMESPACE IN a' this would translate into
+        `GET /namespaces?parent=a` and must return Namepace.of("a","b").
+      operationId: listNamespaces
+      parameters:
+        - name: parent
+          in: query
+          description: Optional parent namespace under which to list namespaces. When empty, list top-level namespaces.
+          required: false
+          schema:
+            type: string
+          example: ?parent=accounting.tax
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListNamespacesResponse'
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found (Parent namespace does not exist)
+    post:
+      tags:
+        - Catalog API
+      summary: Create a namespace
+      description: Create a namespace, with an optional set of properties. The server might also add properties, such as last_modified_time etc.
+      operationId: createNamespace
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateNamespaceRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '409':
+          $ref: '#/components/responses/NamespaceAlreadyExistsResponse'
+
+  /namespaces/{namespace}:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    get:
+      tags:
+        - Catalog API
+      summary: Load the metadata properties for a namespace
+      operationId: loadNamespaceMetadata
+      description: Return all stored metadata properties for a given namespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/GetNamespaceResponse'
+        '404':
+          $ref: '#/components/responses/NoSuchNamespaceResponse'
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a namespace exists
+      operationId: namespaceExists
+      description: Check if a namespace exists.
+      responses:
+        '200':
+          description: OK - Namesapce exists
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a namespace from the catalog. Namespace must be empty.
+      operationId: dropNamespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example: { "data": { "dropped": true } }
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+
+
+  /namespaces/{namespace}/properties:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    post:
+      tags:
+        - Catalog API
+      summary: Set or remove properties on a namespace
+      operationId: setProperties / removeProperties

Review comment:
       I thought it was recommended for operationId to be shaped like program identifiers (which would prevent the use of space and slash?)

##########
File path: rest_docs/rest-catalog-open-api-v0.1.yaml
##########
@@ -0,0 +1,657 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+---
+openapi: 3.0.3
+info:
+  title: Apache Iceberg REST Catalog API
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: 1.0.0
+  description:
+    Defines the specification for the first version of the REST Catalog API. Implementations should support both Iceberg table specs v1 and v2, with priority given to v2.
+servers:
+  - url: https://{host}:{port}/{basePath}
+    variables:
+      host:
+        description: The host address for the specified server
+        default: localhost
+      port:
+        description: The port used when addressing the host
+        default: "443"
+      basePath:
+        default: v1
+  - url: http://127.0.0.1:1080/v1
+    description: URL Used for Mock-Server Unit Tests
+# All routes are currently configured using an Authorization header.
+security:
+  - BearerAuth: []
+paths:
+  /config:
+    get:
+      tags:
+        - Configuration API
+      summary: List all catalog configuration settings
+      operationId: getConfig
+      description: >
+        All REST catalog clients will first call this route to get possible catalog-specific
+        configuration values provided by the server, that the catalog (and its HTTP client)
+        can use to complete the `initialize` step.
+
+        This call is similar to the initial set-up calls that some catalogs already do for
+        domain-specific information, such as the Nessie catalog or the Glue catalog.
+        This is to allow for services that would like to integrate with Iceberg to do so,
+        and to be able to add their own domain-specific information into the REST catalog without
+        requiring them to write and distribute a catalog themselves.
+
+        There will be two sets of values provided -
+
+        - overrides
+          * An object containing values that the client must use.
+            For example, auth headers that the client will receive from the server
+            as temporary credentials.
+        - defaults
+          * Catalog-specific configuration that the client may use as a default value.
+            These are optional and the client is free to use its own value for these.
+
+      responses:
+        default:
+          description: Server-Specific Configuration Values (or Overrides)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/IcebergConfiguration'
+              example: {
+                "data": {
+                  "overrides": {
+                    "prefix": "/raul",
+                    "headers": {
+                      "User-Agent": "Raul",
+                      "Authorization": "Basic Ym9zY236Ym9zY28=",
+                    }
+                  },
+                  "defaults": {
+                    "clients": 5,
+                    "headers": {
+                      "Upgrade-Insecure-Requests": "1"
+                    }
+                  }
+                }
+              }
+        "400":
+          description: Unknown Error
+        "401":
+          description: Unauthorized
+  /namespaces:
+    get:
+      tags:
+        - Catalog API
+      summary: List namespaces, optionally providing a parent namespace to list underneaath
+      description:
+        List all namespaces at a certain level, optionally starting from a given parent namespace.
+        For example, if table a.b.t exists, using 'SELECT NAMESPACE IN a' this would translate into
+        `GET /namespaces?parent=a` and must return Namepace.of("a","b").
+      operationId: listNamespaces
+      parameters:
+        - name: parent
+          in: query
+          description: Optional parent namespace under which to list namespaces. When empty, list top-level namespaces.
+          required: false
+          schema:
+            type: string
+          example: ?parent=accounting.tax
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListNamespacesResponse'
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found (Parent namespace does not exist)
+    post:
+      tags:
+        - Catalog API
+      summary: Create a namespace
+      description: Create a namespace, with an optional set of properties. The server might also add properties, such as last_modified_time etc.
+      operationId: createNamespace
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateNamespaceRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '409':
+          $ref: '#/components/responses/NamespaceAlreadyExistsResponse'
+
+  /namespaces/{namespace}:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    get:
+      tags:
+        - Catalog API
+      summary: Load the metadata properties for a namespace
+      operationId: loadNamespaceMetadata
+      description: Return all stored metadata properties for a given namespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/GetNamespaceResponse'
+        '404':
+          $ref: '#/components/responses/NoSuchNamespaceResponse'
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a namespace exists
+      operationId: namespaceExists
+      description: Check if a namespace exists.
+      responses:
+        '200':
+          description: OK - Namesapce exists
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a namespace from the catalog. Namespace must be empty.
+      operationId: dropNamespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example: { "data": { "dropped": true } }
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+
+
+  /namespaces/{namespace}/properties:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    post:
+      tags:
+        - Catalog API
+      summary: Set or remove properties on a namespace
+      operationId: setProperties / removeProperties
+      description:
+        Set and/or remove a collection or properties on a namespae.
+        The request body specifies a list of properties to remove and a map
+        of key value pairs to update.
+
+        Properties that are not in the request are not modified or removed by this call.
+        Server implementations are not required to support namespace properties.
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/UpdatePropertiesRequest'
+            example:
+              { "toRemove": [ "foo", "bar" ], "toUpdate": { "owner": "Raoul" } }
+        required: true
+      responses:
+        200:
+          description: OK
+          content:
+            'application/json':
+              schema:
+                # This is an IcebergResponseObject<SetPropertiesResponse>, in that it uses the standard wrapper of { "data": toJson(SetPropertiesResponse) }
+                $ref: '#/components/schemas/UpdatePropertiesResponse'
+              example: {
+                "data": {
+                  "updated": [ "owner" ],
+                  "removed": [ "foo" ],
+                  "notPresent": [ "bar" ]
+                }
+              }
+        404:
+          description: Not Found (NoSuchNamespaceException)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example:
+                { "error": { "message": "Namespace does not exist", "type": "NoSuchNamespaceException", "code": 404 } }
+        406:
+          description: Not Acceptable (Unsupported Operation)
+        422:
+          description: Unprocessable Entity. A property key was included in both toRemove and toUpdate.
+
+  /namespaces/{namespace}/tables:
+    parameters:
+      - name: namespace
+        description: A namespace identifier under which to list tables
+        in: path
+        required: true
+        schema:
+          type: string
+        examples:
+          singlepart_namespace:
+            value: "accounting"
+          multipart_namespace:
+            value: "accounting.tax"
+    get:
+      tags:
+        - Catalog API
+      summary: List all table identifiers underneath a given namespace
+      description: Return all table identifiers under this namespace
+      operationId: listTables
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListTablesResponse'
+        '404':
+          description: Not Found (NoSuchNamespaceException)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example:
+                '{ error: { message: "Namespace does not exist", type: "NoSuchNamespaceException", code: 404 }'
+
+  /namespaces/{namespace}/tables/{table}:
+    parameters:
+      - name: namespace
+        in: path
+        description: A namespace identifier
+        required: true
+        schema:
+          type: string
+        examples:
+          singlepart_namespace:
+            value: "accounting"
+          multipart_namespace:
+            value: "accounting.tax"
+      - name: table
+        in: path
+        description: A table name
+        required: true
+        schema:
+          type: string
+        example: "sales"
+
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a table from the catalog
+      operationId: dropTable
+      description: Remove a table from the catalog
+      parameters:
+        - name: purgeRequested
+          in: query
+          required: false
+          description: Whether the user requested to purge the underlying table's data and metadata
+          schema:
+            type: boolean
+            default: false
+      responses:
+        200:
+          description: OK
+          content:
+            'application/json':
+              schema:
+                $ref: '#/components/schemas/DropTableResponse'
+              example: { "data": { "dropped": true, "purged": false } }
+        202:
+          # TODO - Add a callback or handle to check on the state of an async purge request
+          description: Accepted - for use if purgeRequested is implemented as an asynchronous action.
+        404:
+          $ref: '#/components/responses/NoSuchTableResponse'
+
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a table exists
+      operationId: tableExists
+      description:
+        Check if a table exists within a given namespace.
+      responses:
+        200:
+          description: OK - Table Exists
+        401:
+          description: Unauthorized
+        404:
+          description: Not Found
+
+  /tables/rename:
+    post:
+      tags:
+        - Catalog API
+      summary: Rename a table from its current name to a new name
+      description:
+        Rename a table from one identifier to another. It's valid to move a table
+        across namespaces, but the server implementation doesn't need to support it.
+      operationId: renameTable
+      requestBody:
+        description: Current table identifier to rename and new table identifier to rename to
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/RenameTableRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '404':
+          description:
+            Not Found
+            - NoSuchTableException, Table to rename does not exist
+            - NoSuchNamespaceException, The target namespace of the new table identifier does not exist
+          content:
+            application/json:
+              schema:
+                oneOf:
+                  - $ref: '#/components/responses/NoSuchTableResponse'
+                  - $ref: '#/components/responses/NoSuchNamespaceResponse'
+              examples:
+                table_to_rename_does_not_exist:
+                  value: {
+                    "error": {
+                      "message": "Table to rename does not exist",
+                      "type": "NoSuchTableException",
+                      "code": 404
+                    } }
+                namespace_to_rename_to_does_not_exist:
+                  value: {
+                    "error": {
+                      "message": "Namespace to rename to does not exist",
+                      "type": "NoSuchNameSpaceException",
+                      "code": 404
+                    } }
+        '406':
+          description: Not Acceptable (UnsupportedOperationException)
+        '409':
+          description: Conflict (AlreadyExistsException - The new target table identifier already exists)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/TableAlreadyExistsError'
+              example: {
+                "error": {
+                  "message": "Table already exists",
+                  "type": "AlreadyExistsException",
+                  "code": 409
+                } }
+
+components:
+
+  ##############################
+  # Application Schema Objects #
+  ##############################
+  schemas:
+    ResponseDataObject:
+      type: object
+      description: JSON data payload returned in a successful response body
+      properties:
+        data:
+          type: object
+          description: Wrapper for the response of a successful request
+      example: { "data": { "identifiers": [ "office.employees", "office.dogs", "office.cats" ] } }
+    ResponseErrorObject:
+      type: object
+      description: JSON error payload returned in a response with further details on the error
+      required:
+        - message
+        - type
+        - code
+      properties:
+        message:
+          type: string
+          description: Human-readable error message
+        type:
+          type: string
+          description: Internal type of the error, such as an exception class
+          example: NoSuchNamespaceException
+        code:
+          type: integer
+          minimum: 100

Review comment:
       do we expect http status codes below 400?

##########
File path: rest_docs/rest-catalog-open-api-v0.1.yaml
##########
@@ -0,0 +1,657 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+---
+openapi: 3.0.3
+info:
+  title: Apache Iceberg REST Catalog API
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: 1.0.0
+  description:
+    Defines the specification for the first version of the REST Catalog API. Implementations should support both Iceberg table specs v1 and v2, with priority given to v2.
+servers:
+  - url: https://{host}:{port}/{basePath}
+    variables:
+      host:
+        description: The host address for the specified server
+        default: localhost
+      port:
+        description: The port used when addressing the host
+        default: "443"
+      basePath:
+        default: v1
+  - url: http://127.0.0.1:1080/v1
+    description: URL Used for Mock-Server Unit Tests
+# All routes are currently configured using an Authorization header.
+security:
+  - BearerAuth: []
+paths:
+  /config:
+    get:
+      tags:
+        - Configuration API
+      summary: List all catalog configuration settings
+      operationId: getConfig
+      description: >
+        All REST catalog clients will first call this route to get possible catalog-specific
+        configuration values provided by the server, that the catalog (and its HTTP client)
+        can use to complete the `initialize` step.
+
+        This call is similar to the initial set-up calls that some catalogs already do for
+        domain-specific information, such as the Nessie catalog or the Glue catalog.
+        This is to allow for services that would like to integrate with Iceberg to do so,
+        and to be able to add their own domain-specific information into the REST catalog without
+        requiring them to write and distribute a catalog themselves.
+
+        There will be two sets of values provided -
+
+        - overrides
+          * An object containing values that the client must use.
+            For example, auth headers that the client will receive from the server
+            as temporary credentials.
+        - defaults
+          * Catalog-specific configuration that the client may use as a default value.
+            These are optional and the client is free to use its own value for these.
+
+      responses:
+        default:
+          description: Server-Specific Configuration Values (or Overrides)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/IcebergConfiguration'
+              example: {
+                "data": {
+                  "overrides": {
+                    "prefix": "/raul",
+                    "headers": {
+                      "User-Agent": "Raul",
+                      "Authorization": "Basic Ym9zY236Ym9zY28=",
+                    }
+                  },
+                  "defaults": {
+                    "clients": 5,
+                    "headers": {
+                      "Upgrade-Insecure-Requests": "1"
+                    }
+                  }
+                }
+              }
+        "400":
+          description: Unknown Error
+        "401":
+          description: Unauthorized
+  /namespaces:
+    get:
+      tags:
+        - Catalog API
+      summary: List namespaces, optionally providing a parent namespace to list underneaath
+      description:
+        List all namespaces at a certain level, optionally starting from a given parent namespace.
+        For example, if table a.b.t exists, using 'SELECT NAMESPACE IN a' this would translate into
+        `GET /namespaces?parent=a` and must return Namepace.of("a","b").
+      operationId: listNamespaces
+      parameters:
+        - name: parent
+          in: query
+          description: Optional parent namespace under which to list namespaces. When empty, list top-level namespaces.
+          required: false
+          schema:
+            type: string
+          example: ?parent=accounting.tax
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListNamespacesResponse'
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found (Parent namespace does not exist)
+    post:
+      tags:
+        - Catalog API
+      summary: Create a namespace
+      description: Create a namespace, with an optional set of properties. The server might also add properties, such as last_modified_time etc.
+      operationId: createNamespace
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateNamespaceRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '409':
+          $ref: '#/components/responses/NamespaceAlreadyExistsResponse'
+
+  /namespaces/{namespace}:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    get:
+      tags:
+        - Catalog API
+      summary: Load the metadata properties for a namespace
+      operationId: loadNamespaceMetadata
+      description: Return all stored metadata properties for a given namespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/GetNamespaceResponse'
+        '404':
+          $ref: '#/components/responses/NoSuchNamespaceResponse'
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a namespace exists
+      operationId: namespaceExists
+      description: Check if a namespace exists.
+      responses:
+        '200':
+          description: OK - Namesapce exists
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a namespace from the catalog. Namespace must be empty.
+      operationId: dropNamespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example: { "data": { "dropped": true } }
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+
+
+  /namespaces/{namespace}/properties:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    post:
+      tags:
+        - Catalog API
+      summary: Set or remove properties on a namespace
+      operationId: setProperties / removeProperties
+      description:
+        Set and/or remove a collection or properties on a namespae.
+        The request body specifies a list of properties to remove and a map
+        of key value pairs to update.
+
+        Properties that are not in the request are not modified or removed by this call.
+        Server implementations are not required to support namespace properties.
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/UpdatePropertiesRequest'
+            example:
+              { "toRemove": [ "foo", "bar" ], "toUpdate": { "owner": "Raoul" } }
+        required: true
+      responses:
+        200:
+          description: OK
+          content:
+            'application/json':
+              schema:
+                # This is an IcebergResponseObject<SetPropertiesResponse>, in that it uses the standard wrapper of { "data": toJson(SetPropertiesResponse) }
+                $ref: '#/components/schemas/UpdatePropertiesResponse'
+              example: {
+                "data": {
+                  "updated": [ "owner" ],
+                  "removed": [ "foo" ],
+                  "notPresent": [ "bar" ]
+                }
+              }
+        404:
+          description: Not Found (NoSuchNamespaceException)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example:
+                { "error": { "message": "Namespace does not exist", "type": "NoSuchNamespaceException", "code": 404 } }
+        406:
+          description: Not Acceptable (Unsupported Operation)
+        422:
+          description: Unprocessable Entity. A property key was included in both toRemove and toUpdate.
+
+  /namespaces/{namespace}/tables:
+    parameters:
+      - name: namespace
+        description: A namespace identifier under which to list tables
+        in: path
+        required: true
+        schema:
+          type: string
+        examples:
+          singlepart_namespace:
+            value: "accounting"
+          multipart_namespace:
+            value: "accounting.tax"
+    get:
+      tags:
+        - Catalog API
+      summary: List all table identifiers underneath a given namespace
+      description: Return all table identifiers under this namespace
+      operationId: listTables
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListTablesResponse'
+        '404':
+          description: Not Found (NoSuchNamespaceException)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example:
+                '{ error: { message: "Namespace does not exist", type: "NoSuchNamespaceException", code: 404 }'
+
+  /namespaces/{namespace}/tables/{table}:
+    parameters:
+      - name: namespace
+        in: path
+        description: A namespace identifier
+        required: true
+        schema:
+          type: string
+        examples:
+          singlepart_namespace:
+            value: "accounting"
+          multipart_namespace:
+            value: "accounting.tax"
+      - name: table
+        in: path
+        description: A table name
+        required: true
+        schema:
+          type: string
+        example: "sales"
+
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a table from the catalog
+      operationId: dropTable
+      description: Remove a table from the catalog
+      parameters:
+        - name: purgeRequested
+          in: query
+          required: false
+          description: Whether the user requested to purge the underlying table's data and metadata
+          schema:
+            type: boolean
+            default: false
+      responses:
+        200:
+          description: OK
+          content:
+            'application/json':
+              schema:
+                $ref: '#/components/schemas/DropTableResponse'
+              example: { "data": { "dropped": true, "purged": false } }
+        202:
+          # TODO - Add a callback or handle to check on the state of an async purge request
+          description: Accepted - for use if purgeRequested is implemented as an asynchronous action.
+        404:
+          $ref: '#/components/responses/NoSuchTableResponse'
+
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a table exists
+      operationId: tableExists
+      description:
+        Check if a table exists within a given namespace.
+      responses:
+        200:
+          description: OK - Table Exists
+        401:
+          description: Unauthorized
+        404:
+          description: Not Found
+
+  /tables/rename:
+    post:
+      tags:
+        - Catalog API
+      summary: Rename a table from its current name to a new name
+      description:
+        Rename a table from one identifier to another. It's valid to move a table
+        across namespaces, but the server implementation doesn't need to support it.
+      operationId: renameTable
+      requestBody:
+        description: Current table identifier to rename and new table identifier to rename to
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/RenameTableRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '404':
+          description:
+            Not Found
+            - NoSuchTableException, Table to rename does not exist
+            - NoSuchNamespaceException, The target namespace of the new table identifier does not exist
+          content:
+            application/json:
+              schema:
+                oneOf:
+                  - $ref: '#/components/responses/NoSuchTableResponse'
+                  - $ref: '#/components/responses/NoSuchNamespaceResponse'
+              examples:
+                table_to_rename_does_not_exist:
+                  value: {
+                    "error": {
+                      "message": "Table to rename does not exist",
+                      "type": "NoSuchTableException",
+                      "code": 404
+                    } }
+                namespace_to_rename_to_does_not_exist:
+                  value: {
+                    "error": {
+                      "message": "Namespace to rename to does not exist",
+                      "type": "NoSuchNameSpaceException",
+                      "code": 404
+                    } }
+        '406':
+          description: Not Acceptable (UnsupportedOperationException)
+        '409':
+          description: Conflict (AlreadyExistsException - The new target table identifier already exists)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/TableAlreadyExistsError'
+              example: {
+                "error": {
+                  "message": "Table already exists",
+                  "type": "AlreadyExistsException",
+                  "code": 409
+                } }
+
+components:
+
+  ##############################
+  # Application Schema Objects #
+  ##############################
+  schemas:
+    ResponseDataObject:
+      type: object
+      description: JSON data payload returned in a successful response body
+      properties:
+        data:
+          type: object
+          description: Wrapper for the response of a successful request
+      example: { "data": { "identifiers": [ "office.employees", "office.dogs", "office.cats" ] } }
+    ResponseErrorObject:
+      type: object
+      description: JSON error payload returned in a response with further details on the error
+      required:
+        - message
+        - type
+        - code
+      properties:
+        message:
+          type: string
+          description: Human-readable error message
+        type:
+          type: string
+          description: Internal type of the error, such as an exception class
+          example: NoSuchNamespaceException
+        code:
+          type: integer
+          minimum: 100
+          maximum: 600
+          description: HTTP response code
+          example: 404
+    TableIdentifier:
+      type: object
+      required:
+        - namespace
+      properties:
+        namespace:
+          type: array
+          description: Individual levels of the namespace
+          items:
+            type: string
+          nullable: false
+        name:
+          type: string
+          nullable: false
+    CreateNamespaceRequest:
+      type: object
+      required:
+        - namespace
+      properties:
+        namespace:
+          type: array
+          description: Individual levels of the namespace
+          items:
+            type: string
+        properties:
+          type: object
+          description: Configuration properties for the namespace
+          example: '{ "owner": "Hank Bendickson" }'
+    RenameTableRequest:
+      type: object
+      properties:
+        sourceTableIdentifier:
+          $ref: '#/components/schemas/TableIdentifier'
+        destinationTableIdentifier:
+          $ref: '#/components/schemas/TableIdentifier'
+    UpdatePropertiesRequest:
+      type: object
+      properties:
+        toRemove:
+          type: array
+          uniqueItems: true
+          items:
+            type: string
+          example: '[ "department", "access_group" ]'
+        toUpdate:
+          uniqueItems: true
+          type: object
+          items:
+            type: string
+          example: { "owner": "Hank Bendickson" }
+    UpdatePropertiesResponse:
+      type: object
+      description: JSON data response for a synchronous update properties request.
+      properties:
+        updated:
+          type: array
+          items:
+            type: string
+            description: List of property keys that were added or udpated
+        removed:
+          type: array
+          items:
+            type: string
+          description: List of properties that were removed (and not updated)
+        notPresent:
+          type: array
+          items:
+            type: string
+            description:
+              List of properties requested for removal that were not found
+              in the namespace's properties.
+              Represents a partial success response.
+              Server's do not need to implement this.
+    ListNamespacesResponse:
+      type: object
+      properties:
+        namespaces:
+          type: array
+          items:
+            $ref: '#/components/schemas/Namespace'
+    DropTableResponse:
+      type: object
+      properties:
+        dropped:
+          type: boolean
+          description: true if the table was found and removed from the catalog
+        purged:
+          type: boolean
+          description: whether the underlying data was purged or is being purged
+    Namespace:
+      type: array
+      description: Reference to one or more levels of a namespace
+      items:
+        type: string
+      example: [ "accounting", "tax" ]
+    GetNamespaceResponse:
+      type: object
+      properties:
+        namespace:
+          $ref: '#/components/schemas/Namespace'
+        properties:
+          type: object
+          example: { "owner": "Ralph", 'transient_lastDdlTime': '1452120468' }
+    ListTablesResponse:
+      type: object
+      properties:
+        identifiers:
+          type: array
+          items:
+            $ref: '#/components/schemas/TableIdentifier'
+    IcebergConfiguration:
+      type: object
+      description: "Server-provided configuration for the catalog."
+      properties:
+        rootPath:
+          minLength: 1
+          type: string
+          default: /
+          nullable: false
+          description:
+            Root path to be used for all other requests. Server-side implementations
+            are free to use another choice for root path, but must conform to the
+            specification otherwise in order to interoperate with the URI generation
+            that the REST catalog client will do.
+        catalogProperties:
+          type: object
+          nullable: true
+          description:
+            An optional field for storing catalog configuration properties that
+            are stored server side. This could be beneifical to an administrator,
+            for example to enforce that a given LocationProvider is used or to
+            enforce that a certain FileIO implementation is used.
+
+    TableAlreadyExistsError:
+      allOf:
+        - $ref: '#/components/schemas/ResponseErrorObject'
+      description: the given table identifier already exists and cannot be created / renamed to
+
+  #############################
+  # Reusable Response Objects #
+  #############################
+  responses:
+
+    IcebergResponseObject:
+      description: JSON wrapper for all response bodies, with a data object and / or an error object
+      content:
+        application/json:
+          schema:
+            anyOf:
+              - $ref: '#/components/schemas/ResponseDataObject'
+              - $ref: '#/components/schemas/ResponseErrorObject'
+          example: { "data": { "namespaces": [ [ "ns1", "foo_db" ], [ "ns1", "bar_db" ] ] }, "error": { } }

Review comment:
       should it be `anyOf` or `oneOf`? Wouldn't that make it even more confusing if the response has both a data and an error field?

##########
File path: rest_docs/rest-catalog-open-api-v0.1.yaml
##########
@@ -0,0 +1,657 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+---
+openapi: 3.0.3
+info:
+  title: Apache Iceberg REST Catalog API
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: 1.0.0
+  description:
+    Defines the specification for the first version of the REST Catalog API. Implementations should support both Iceberg table specs v1 and v2, with priority given to v2.
+servers:
+  - url: https://{host}:{port}/{basePath}
+    variables:
+      host:
+        description: The host address for the specified server
+        default: localhost
+      port:
+        description: The port used when addressing the host
+        default: "443"
+      basePath:
+        default: v1
+  - url: http://127.0.0.1:1080/v1
+    description: URL Used for Mock-Server Unit Tests
+# All routes are currently configured using an Authorization header.
+security:
+  - BearerAuth: []
+paths:
+  /config:
+    get:
+      tags:
+        - Configuration API
+      summary: List all catalog configuration settings
+      operationId: getConfig
+      description: >
+        All REST catalog clients will first call this route to get possible catalog-specific
+        configuration values provided by the server, that the catalog (and its HTTP client)
+        can use to complete the `initialize` step.
+
+        This call is similar to the initial set-up calls that some catalogs already do for
+        domain-specific information, such as the Nessie catalog or the Glue catalog.
+        This is to allow for services that would like to integrate with Iceberg to do so,
+        and to be able to add their own domain-specific information into the REST catalog without
+        requiring them to write and distribute a catalog themselves.
+
+        There will be two sets of values provided -
+
+        - overrides
+          * An object containing values that the client must use.
+            For example, auth headers that the client will receive from the server
+            as temporary credentials.
+        - defaults
+          * Catalog-specific configuration that the client may use as a default value.
+            These are optional and the client is free to use its own value for these.
+
+      responses:
+        default:
+          description: Server-Specific Configuration Values (or Overrides)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/IcebergConfiguration'
+              example: {
+                "data": {
+                  "overrides": {
+                    "prefix": "/raul",
+                    "headers": {
+                      "User-Agent": "Raul",
+                      "Authorization": "Basic Ym9zY236Ym9zY28=",
+                    }
+                  },
+                  "defaults": {
+                    "clients": 5,
+                    "headers": {
+                      "Upgrade-Insecure-Requests": "1"
+                    }
+                  }
+                }
+              }
+        "400":
+          description: Unknown Error
+        "401":
+          description: Unauthorized
+  /namespaces:
+    get:
+      tags:
+        - Catalog API
+      summary: List namespaces, optionally providing a parent namespace to list underneaath
+      description:
+        List all namespaces at a certain level, optionally starting from a given parent namespace.
+        For example, if table a.b.t exists, using 'SELECT NAMESPACE IN a' this would translate into
+        `GET /namespaces?parent=a` and must return Namepace.of("a","b").
+      operationId: listNamespaces
+      parameters:
+        - name: parent
+          in: query
+          description: Optional parent namespace under which to list namespaces. When empty, list top-level namespaces.
+          required: false
+          schema:
+            type: string
+          example: ?parent=accounting.tax
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListNamespacesResponse'
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found (Parent namespace does not exist)
+    post:
+      tags:
+        - Catalog API
+      summary: Create a namespace
+      description: Create a namespace, with an optional set of properties. The server might also add properties, such as last_modified_time etc.
+      operationId: createNamespace
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateNamespaceRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '409':
+          $ref: '#/components/responses/NamespaceAlreadyExistsResponse'
+
+  /namespaces/{namespace}:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    get:
+      tags:
+        - Catalog API
+      summary: Load the metadata properties for a namespace
+      operationId: loadNamespaceMetadata
+      description: Return all stored metadata properties for a given namespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/GetNamespaceResponse'
+        '404':
+          $ref: '#/components/responses/NoSuchNamespaceResponse'
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a namespace exists
+      operationId: namespaceExists
+      description: Check if a namespace exists.
+      responses:
+        '200':
+          description: OK - Namesapce exists
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a namespace from the catalog. Namespace must be empty.
+      operationId: dropNamespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example: { "data": { "dropped": true } }
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+
+
+  /namespaces/{namespace}/properties:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    post:
+      tags:
+        - Catalog API
+      summary: Set or remove properties on a namespace
+      operationId: setProperties / removeProperties
+      description:
+        Set and/or remove a collection or properties on a namespae.
+        The request body specifies a list of properties to remove and a map
+        of key value pairs to update.
+
+        Properties that are not in the request are not modified or removed by this call.
+        Server implementations are not required to support namespace properties.
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/UpdatePropertiesRequest'
+            example:
+              { "toRemove": [ "foo", "bar" ], "toUpdate": { "owner": "Raoul" } }
+        required: true
+      responses:
+        200:
+          description: OK
+          content:
+            'application/json':
+              schema:
+                # This is an IcebergResponseObject<SetPropertiesResponse>, in that it uses the standard wrapper of { "data": toJson(SetPropertiesResponse) }
+                $ref: '#/components/schemas/UpdatePropertiesResponse'
+              example: {
+                "data": {
+                  "updated": [ "owner" ],
+                  "removed": [ "foo" ],
+                  "notPresent": [ "bar" ]
+                }
+              }
+        404:
+          description: Not Found (NoSuchNamespaceException)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example:
+                { "error": { "message": "Namespace does not exist", "type": "NoSuchNamespaceException", "code": 404 } }
+        406:
+          description: Not Acceptable (Unsupported Operation)
+        422:
+          description: Unprocessable Entity. A property key was included in both toRemove and toUpdate.
+
+  /namespaces/{namespace}/tables:
+    parameters:
+      - name: namespace
+        description: A namespace identifier under which to list tables
+        in: path
+        required: true
+        schema:
+          type: string
+        examples:
+          singlepart_namespace:
+            value: "accounting"
+          multipart_namespace:
+            value: "accounting.tax"
+    get:
+      tags:
+        - Catalog API
+      summary: List all table identifiers underneath a given namespace
+      description: Return all table identifiers under this namespace
+      operationId: listTables
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListTablesResponse'
+        '404':
+          description: Not Found (NoSuchNamespaceException)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example:
+                '{ error: { message: "Namespace does not exist", type: "NoSuchNamespaceException", code: 404 }'
+
+  /namespaces/{namespace}/tables/{table}:
+    parameters:
+      - name: namespace
+        in: path
+        description: A namespace identifier
+        required: true
+        schema:
+          type: string
+        examples:
+          singlepart_namespace:
+            value: "accounting"
+          multipart_namespace:
+            value: "accounting.tax"
+      - name: table
+        in: path
+        description: A table name
+        required: true
+        schema:
+          type: string
+        example: "sales"
+
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a table from the catalog
+      operationId: dropTable
+      description: Remove a table from the catalog
+      parameters:
+        - name: purgeRequested
+          in: query
+          required: false
+          description: Whether the user requested to purge the underlying table's data and metadata
+          schema:
+            type: boolean
+            default: false
+      responses:
+        200:
+          description: OK
+          content:
+            'application/json':
+              schema:
+                $ref: '#/components/schemas/DropTableResponse'
+              example: { "data": { "dropped": true, "purged": false } }
+        202:
+          # TODO - Add a callback or handle to check on the state of an async purge request
+          description: Accepted - for use if purgeRequested is implemented as an asynchronous action.
+        404:
+          $ref: '#/components/responses/NoSuchTableResponse'
+
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a table exists
+      operationId: tableExists
+      description:
+        Check if a table exists within a given namespace.
+      responses:
+        200:
+          description: OK - Table Exists
+        401:
+          description: Unauthorized
+        404:
+          description: Not Found
+
+  /tables/rename:
+    post:
+      tags:
+        - Catalog API
+      summary: Rename a table from its current name to a new name
+      description:
+        Rename a table from one identifier to another. It's valid to move a table
+        across namespaces, but the server implementation doesn't need to support it.
+      operationId: renameTable
+      requestBody:
+        description: Current table identifier to rename and new table identifier to rename to
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/RenameTableRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '404':
+          description:
+            Not Found
+            - NoSuchTableException, Table to rename does not exist
+            - NoSuchNamespaceException, The target namespace of the new table identifier does not exist
+          content:
+            application/json:
+              schema:
+                oneOf:
+                  - $ref: '#/components/responses/NoSuchTableResponse'
+                  - $ref: '#/components/responses/NoSuchNamespaceResponse'
+              examples:
+                table_to_rename_does_not_exist:
+                  value: {
+                    "error": {
+                      "message": "Table to rename does not exist",
+                      "type": "NoSuchTableException",
+                      "code": 404
+                    } }
+                namespace_to_rename_to_does_not_exist:
+                  value: {
+                    "error": {
+                      "message": "Namespace to rename to does not exist",
+                      "type": "NoSuchNameSpaceException",
+                      "code": 404
+                    } }
+        '406':
+          description: Not Acceptable (UnsupportedOperationException)
+        '409':
+          description: Conflict (AlreadyExistsException - The new target table identifier already exists)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/TableAlreadyExistsError'
+              example: {
+                "error": {
+                  "message": "Table already exists",
+                  "type": "AlreadyExistsException",
+                  "code": 409
+                } }
+
+components:
+
+  ##############################
+  # Application Schema Objects #
+  ##############################
+  schemas:
+    ResponseDataObject:
+      type: object
+      description: JSON data payload returned in a successful response body
+      properties:
+        data:
+          type: object
+          description: Wrapper for the response of a successful request
+      example: { "data": { "identifiers": [ "office.employees", "office.dogs", "office.cats" ] } }
+    ResponseErrorObject:
+      type: object
+      description: JSON error payload returned in a response with further details on the error
+      required:
+        - message
+        - type
+        - code
+      properties:
+        message:
+          type: string
+          description: Human-readable error message
+        type:
+          type: string
+          description: Internal type of the error, such as an exception class
+          example: NoSuchNamespaceException
+        code:
+          type: integer
+          minimum: 100
+          maximum: 600
+          description: HTTP response code
+          example: 404
+    TableIdentifier:
+      type: object
+      required:
+        - namespace
+      properties:
+        namespace:
+          type: array
+          description: Individual levels of the namespace
+          items:
+            type: string
+          nullable: false
+        name:
+          type: string
+          nullable: false
+    CreateNamespaceRequest:
+      type: object
+      required:
+        - namespace
+      properties:
+        namespace:
+          type: array
+          description: Individual levels of the namespace
+          items:
+            type: string
+        properties:
+          type: object
+          description: Configuration properties for the namespace
+          example: '{ "owner": "Hank Bendickson" }'
+    RenameTableRequest:
+      type: object
+      properties:
+        sourceTableIdentifier:
+          $ref: '#/components/schemas/TableIdentifier'
+        destinationTableIdentifier:
+          $ref: '#/components/schemas/TableIdentifier'
+    UpdatePropertiesRequest:
+      type: object
+      properties:
+        toRemove:
+          type: array
+          uniqueItems: true
+          items:
+            type: string
+          example: '[ "department", "access_group" ]'
+        toUpdate:
+          uniqueItems: true
+          type: object
+          items:
+            type: string
+          example: { "owner": "Hank Bendickson" }
+    UpdatePropertiesResponse:
+      type: object
+      description: JSON data response for a synchronous update properties request.
+      properties:
+        updated:
+          type: array
+          items:
+            type: string
+            description: List of property keys that were added or udpated
+        removed:
+          type: array
+          items:
+            type: string
+          description: List of properties that were removed (and not updated)
+        notPresent:
+          type: array
+          items:
+            type: string
+            description:
+              List of properties requested for removal that were not found
+              in the namespace's properties.
+              Represents a partial success response.
+              Server's do not need to implement this.
+    ListNamespacesResponse:
+      type: object
+      properties:
+        namespaces:
+          type: array
+          items:
+            $ref: '#/components/schemas/Namespace'
+    DropTableResponse:
+      type: object
+      properties:
+        dropped:
+          type: boolean
+          description: true if the table was found and removed from the catalog
+        purged:
+          type: boolean
+          description: whether the underlying data was purged or is being purged
+    Namespace:
+      type: array
+      description: Reference to one or more levels of a namespace
+      items:
+        type: string
+      example: [ "accounting", "tax" ]
+    GetNamespaceResponse:
+      type: object
+      properties:
+        namespace:
+          $ref: '#/components/schemas/Namespace'
+        properties:
+          type: object
+          example: { "owner": "Ralph", 'transient_lastDdlTime': '1452120468' }
+    ListTablesResponse:
+      type: object
+      properties:
+        identifiers:
+          type: array
+          items:
+            $ref: '#/components/schemas/TableIdentifier'
+    IcebergConfiguration:
+      type: object
+      description: "Server-provided configuration for the catalog."
+      properties:
+        rootPath:
+          minLength: 1
+          type: string
+          default: /
+          nullable: false
+          description:
+            Root path to be used for all other requests. Server-side implementations
+            are free to use another choice for root path, but must conform to the
+            specification otherwise in order to interoperate with the URI generation
+            that the REST catalog client will do.
+        catalogProperties:
+          type: object
+          nullable: true
+          description:
+            An optional field for storing catalog configuration properties that
+            are stored server side. This could be beneifical to an administrator,

Review comment:
       typo: beneficial

##########
File path: rest_docs/rest-catalog-open-api-v0.1.yaml
##########
@@ -0,0 +1,657 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+---
+openapi: 3.0.3
+info:
+  title: Apache Iceberg REST Catalog API
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: 1.0.0
+  description:
+    Defines the specification for the first version of the REST Catalog API. Implementations should support both Iceberg table specs v1 and v2, with priority given to v2.
+servers:
+  - url: https://{host}:{port}/{basePath}
+    variables:
+      host:
+        description: The host address for the specified server
+        default: localhost
+      port:
+        description: The port used when addressing the host
+        default: "443"
+      basePath:
+        default: v1
+  - url: http://127.0.0.1:1080/v1
+    description: URL Used for Mock-Server Unit Tests
+# All routes are currently configured using an Authorization header.
+security:
+  - BearerAuth: []
+paths:
+  /config:
+    get:
+      tags:
+        - Configuration API
+      summary: List all catalog configuration settings
+      operationId: getConfig
+      description: >
+        All REST catalog clients will first call this route to get possible catalog-specific
+        configuration values provided by the server, that the catalog (and its HTTP client)
+        can use to complete the `initialize` step.
+
+        This call is similar to the initial set-up calls that some catalogs already do for
+        domain-specific information, such as the Nessie catalog or the Glue catalog.
+        This is to allow for services that would like to integrate with Iceberg to do so,
+        and to be able to add their own domain-specific information into the REST catalog without
+        requiring them to write and distribute a catalog themselves.
+
+        There will be two sets of values provided -
+
+        - overrides
+          * An object containing values that the client must use.
+            For example, auth headers that the client will receive from the server
+            as temporary credentials.
+        - defaults
+          * Catalog-specific configuration that the client may use as a default value.
+            These are optional and the client is free to use its own value for these.
+
+      responses:
+        default:
+          description: Server-Specific Configuration Values (or Overrides)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/IcebergConfiguration'
+              example: {
+                "data": {
+                  "overrides": {
+                    "prefix": "/raul",
+                    "headers": {
+                      "User-Agent": "Raul",
+                      "Authorization": "Basic Ym9zY236Ym9zY28=",
+                    }
+                  },
+                  "defaults": {
+                    "clients": 5,
+                    "headers": {
+                      "Upgrade-Insecure-Requests": "1"
+                    }
+                  }
+                }
+              }
+        "400":
+          description: Unknown Error
+        "401":
+          description: Unauthorized
+  /namespaces:
+    get:
+      tags:
+        - Catalog API
+      summary: List namespaces, optionally providing a parent namespace to list underneaath
+      description:
+        List all namespaces at a certain level, optionally starting from a given parent namespace.
+        For example, if table a.b.t exists, using 'SELECT NAMESPACE IN a' this would translate into
+        `GET /namespaces?parent=a` and must return Namepace.of("a","b").
+      operationId: listNamespaces
+      parameters:
+        - name: parent
+          in: query
+          description: Optional parent namespace under which to list namespaces. When empty, list top-level namespaces.
+          required: false
+          schema:
+            type: string
+          example: ?parent=accounting.tax
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListNamespacesResponse'
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found (Parent namespace does not exist)
+    post:
+      tags:
+        - Catalog API
+      summary: Create a namespace
+      description: Create a namespace, with an optional set of properties. The server might also add properties, such as last_modified_time etc.
+      operationId: createNamespace
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateNamespaceRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '409':
+          $ref: '#/components/responses/NamespaceAlreadyExistsResponse'
+
+  /namespaces/{namespace}:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    get:
+      tags:
+        - Catalog API
+      summary: Load the metadata properties for a namespace
+      operationId: loadNamespaceMetadata
+      description: Return all stored metadata properties for a given namespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/GetNamespaceResponse'
+        '404':
+          $ref: '#/components/responses/NoSuchNamespaceResponse'
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a namespace exists
+      operationId: namespaceExists
+      description: Check if a namespace exists.
+      responses:
+        '200':
+          description: OK - Namesapce exists
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a namespace from the catalog. Namespace must be empty.
+      operationId: dropNamespace
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example: { "data": { "dropped": true } }
+        '401':
+          description: Unauthorized
+        '404':
+          description: Not Found
+
+
+  /namespaces/{namespace}/properties:
+    parameters:
+      - name: namespace
+        in: path
+        required: true
+        schema:
+          type: string
+    post:
+      tags:
+        - Catalog API
+      summary: Set or remove properties on a namespace
+      operationId: setProperties / removeProperties
+      description:
+        Set and/or remove a collection or properties on a namespae.
+        The request body specifies a list of properties to remove and a map
+        of key value pairs to update.
+
+        Properties that are not in the request are not modified or removed by this call.
+        Server implementations are not required to support namespace properties.
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/UpdatePropertiesRequest'
+            example:
+              { "toRemove": [ "foo", "bar" ], "toUpdate": { "owner": "Raoul" } }
+        required: true
+      responses:
+        200:
+          description: OK
+          content:
+            'application/json':
+              schema:
+                # This is an IcebergResponseObject<SetPropertiesResponse>, in that it uses the standard wrapper of { "data": toJson(SetPropertiesResponse) }
+                $ref: '#/components/schemas/UpdatePropertiesResponse'
+              example: {
+                "data": {
+                  "updated": [ "owner" ],
+                  "removed": [ "foo" ],
+                  "notPresent": [ "bar" ]
+                }
+              }
+        404:
+          description: Not Found (NoSuchNamespaceException)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example:
+                { "error": { "message": "Namespace does not exist", "type": "NoSuchNamespaceException", "code": 404 } }
+        406:
+          description: Not Acceptable (Unsupported Operation)
+        422:
+          description: Unprocessable Entity. A property key was included in both toRemove and toUpdate.
+
+  /namespaces/{namespace}/tables:
+    parameters:
+      - name: namespace
+        description: A namespace identifier under which to list tables
+        in: path
+        required: true
+        schema:
+          type: string
+        examples:
+          singlepart_namespace:
+            value: "accounting"
+          multipart_namespace:
+            value: "accounting.tax"
+    get:
+      tags:
+        - Catalog API
+      summary: List all table identifiers underneath a given namespace
+      description: Return all table identifiers under this namespace
+      operationId: listTables
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ListTablesResponse'
+        '404':
+          description: Not Found (NoSuchNamespaceException)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/responses/IcebergResponseObject'
+              example:
+                '{ error: { message: "Namespace does not exist", type: "NoSuchNamespaceException", code: 404 }'
+
+  /namespaces/{namespace}/tables/{table}:
+    parameters:
+      - name: namespace
+        in: path
+        description: A namespace identifier
+        required: true
+        schema:
+          type: string
+        examples:
+          singlepart_namespace:
+            value: "accounting"
+          multipart_namespace:
+            value: "accounting.tax"
+      - name: table
+        in: path
+        description: A table name
+        required: true
+        schema:
+          type: string
+        example: "sales"
+
+    delete:
+      tags:
+        - Catalog API
+      summary: Drop a table from the catalog
+      operationId: dropTable
+      description: Remove a table from the catalog
+      parameters:
+        - name: purgeRequested
+          in: query
+          required: false
+          description: Whether the user requested to purge the underlying table's data and metadata
+          schema:
+            type: boolean
+            default: false
+      responses:
+        200:
+          description: OK
+          content:
+            'application/json':
+              schema:
+                $ref: '#/components/schemas/DropTableResponse'
+              example: { "data": { "dropped": true, "purged": false } }
+        202:
+          # TODO - Add a callback or handle to check on the state of an async purge request
+          description: Accepted - for use if purgeRequested is implemented as an asynchronous action.
+        404:
+          $ref: '#/components/responses/NoSuchTableResponse'
+
+    head:
+      tags:
+        - Catalog API
+      summary: Check if a table exists
+      operationId: tableExists
+      description:
+        Check if a table exists within a given namespace.
+      responses:
+        200:
+          description: OK - Table Exists
+        401:
+          description: Unauthorized
+        404:
+          description: Not Found
+
+  /tables/rename:
+    post:
+      tags:
+        - Catalog API
+      summary: Rename a table from its current name to a new name
+      description:
+        Rename a table from one identifier to another. It's valid to move a table
+        across namespaces, but the server implementation doesn't need to support it.
+      operationId: renameTable
+      requestBody:
+        description: Current table identifier to rename and new table identifier to rename to
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/RenameTableRequest'
+        required: true
+      responses:
+        '200':
+          description: OK
+        '401':
+          description: Unauthorized
+        '404':
+          description:
+            Not Found
+            - NoSuchTableException, Table to rename does not exist
+            - NoSuchNamespaceException, The target namespace of the new table identifier does not exist
+          content:
+            application/json:
+              schema:
+                oneOf:
+                  - $ref: '#/components/responses/NoSuchTableResponse'
+                  - $ref: '#/components/responses/NoSuchNamespaceResponse'
+              examples:
+                table_to_rename_does_not_exist:
+                  value: {
+                    "error": {
+                      "message": "Table to rename does not exist",
+                      "type": "NoSuchTableException",
+                      "code": 404
+                    } }
+                namespace_to_rename_to_does_not_exist:
+                  value: {
+                    "error": {
+                      "message": "Namespace to rename to does not exist",
+                      "type": "NoSuchNameSpaceException",
+                      "code": 404
+                    } }
+        '406':
+          description: Not Acceptable (UnsupportedOperationException)
+        '409':
+          description: Conflict (AlreadyExistsException - The new target table identifier already exists)
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/TableAlreadyExistsError'
+              example: {
+                "error": {
+                  "message": "Table already exists",
+                  "type": "AlreadyExistsException",
+                  "code": 409
+                } }
+
+components:
+
+  ##############################
+  # Application Schema Objects #
+  ##############################
+  schemas:
+    ResponseDataObject:
+      type: object
+      description: JSON data payload returned in a successful response body
+      properties:
+        data:
+          type: object
+          description: Wrapper for the response of a successful request
+      example: { "data": { "identifiers": [ "office.employees", "office.dogs", "office.cats" ] } }
+    ResponseErrorObject:
+      type: object
+      description: JSON error payload returned in a response with further details on the error
+      required:
+        - message
+        - type
+        - code
+      properties:
+        message:
+          type: string
+          description: Human-readable error message
+        type:
+          type: string
+          description: Internal type of the error, such as an exception class
+          example: NoSuchNamespaceException
+        code:
+          type: integer
+          minimum: 100
+          maximum: 600
+          description: HTTP response code
+          example: 404
+    TableIdentifier:
+      type: object
+      required:
+        - namespace
+      properties:
+        namespace:
+          type: array
+          description: Individual levels of the namespace
+          items:
+            type: string
+          nullable: false
+        name:
+          type: string
+          nullable: false
+    CreateNamespaceRequest:
+      type: object
+      required:
+        - namespace
+      properties:
+        namespace:
+          type: array
+          description: Individual levels of the namespace
+          items:
+            type: string
+        properties:
+          type: object
+          description: Configuration properties for the namespace
+          example: '{ "owner": "Hank Bendickson" }'
+    RenameTableRequest:
+      type: object
+      properties:
+        sourceTableIdentifier:
+          $ref: '#/components/schemas/TableIdentifier'
+        destinationTableIdentifier:
+          $ref: '#/components/schemas/TableIdentifier'
+    UpdatePropertiesRequest:
+      type: object
+      properties:
+        toRemove:
+          type: array
+          uniqueItems: true
+          items:
+            type: string
+          example: '[ "department", "access_group" ]'
+        toUpdate:
+          uniqueItems: true
+          type: object
+          items:
+            type: string
+          example: { "owner": "Hank Bendickson" }
+    UpdatePropertiesResponse:
+      type: object
+      description: JSON data response for a synchronous update properties request.
+      properties:
+        updated:
+          type: array
+          items:
+            type: string
+            description: List of property keys that were added or udpated
+        removed:
+          type: array
+          items:
+            type: string
+          description: List of properties that were removed (and not updated)
+        notPresent:
+          type: array
+          items:
+            type: string
+            description:
+              List of properties requested for removal that were not found
+              in the namespace's properties.
+              Represents a partial success response.
+              Server's do not need to implement this.
+    ListNamespacesResponse:
+      type: object
+      properties:
+        namespaces:
+          type: array
+          items:
+            $ref: '#/components/schemas/Namespace'
+    DropTableResponse:
+      type: object
+      properties:
+        dropped:
+          type: boolean
+          description: true if the table was found and removed from the catalog
+        purged:
+          type: boolean
+          description: whether the underlying data was purged or is being purged
+    Namespace:
+      type: array
+      description: Reference to one or more levels of a namespace
+      items:
+        type: string
+      example: [ "accounting", "tax" ]
+    GetNamespaceResponse:
+      type: object
+      properties:
+        namespace:
+          $ref: '#/components/schemas/Namespace'
+        properties:
+          type: object
+          example: { "owner": "Ralph", 'transient_lastDdlTime': '1452120468' }
+    ListTablesResponse:
+      type: object
+      properties:
+        identifiers:
+          type: array
+          items:
+            $ref: '#/components/schemas/TableIdentifier'
+    IcebergConfiguration:
+      type: object
+      description: "Server-provided configuration for the catalog."
+      properties:
+        rootPath:
+          minLength: 1
+          type: string
+          default: /
+          nullable: false
+          description:
+            Root path to be used for all other requests. Server-side implementations
+            are free to use another choice for root path, but must conform to the
+            specification otherwise in order to interoperate with the URI generation
+            that the REST catalog client will do.
+        catalogProperties:
+          type: object
+          nullable: true
+          description:
+            An optional field for storing catalog configuration properties that
+            are stored server side. This could be beneifical to an administrator,
+            for example to enforce that a given LocationProvider is used or to
+            enforce that a certain FileIO implementation is used.
+
+    TableAlreadyExistsError:
+      allOf:
+        - $ref: '#/components/schemas/ResponseErrorObject'
+      description: the given table identifier already exists and cannot be created / renamed to
+
+  #############################
+  # Reusable Response Objects #
+  #############################
+  responses:
+
+    IcebergResponseObject:

Review comment:
       Wrapping a successful response into another `data` field is not something I have seen many APIs doing. Convention seems to be that the true object to be at the top level? Is the motivation for that choice to be able to quickly identify if the response is an error message from a successful one?

##########
File path: rest_docs/rest-catalog-open-api-v0.1.yaml
##########
@@ -0,0 +1,727 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+---
+openapi: 3.0.3
+info:
+  title: Apache Iceberg REST Catalog API
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: 1.0.0
+  description:
+    Defines the specification for the first version of the REST Catalog API. Implementations should support both Iceberg table specs v1 and v2, with priority given to v2.
+servers:
+  - url: http://127.0.0.1:1080
+    description: URL Used for Mock-Server Unit Tests
+# All routes are currently configured using an Authorization header.
+security:
+  - BearerAuth: []
+paths:
+  /v1/config:
+    get:
+      tags:
+        - Configuration API
+      summary: List all catalog configuration settings
+      operationId: getConfig
+      description:
+        All REST catalogs will be initialized by calling this route. This route
+        will return at least the minimum necessary metadata to initialize the
+        catalog. Optionally, it can also include server-side specific overrides.
+        For example, it might also include information used to initialize this catalog
+        such as the details of the Http connection pooling, etc. This route might
+        also advertise information about operations that are not implemented
+        so that the catalog can eagerly throw or go about another way of performing
+        the desired action.
+      responses:
+        default:
+          description: Server-Specific Configuration Overrides
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/IcebergConfiguration'
+        "400":
+          description: Unknown Error

Review comment:
       Sadly I don't think there's a way yet to have common responses across all operations. See https://swagger.io/docs/specification/describing-responses/ section: `Reusing responses`
   
   Also, 400 is probably not the right code for "Unknown error" but for Bad Request (as in the client submitted some bad request). I would assume this is a 500 error code...
   
   I'm also guessing that if 401 is returned, 403 (Forbidden) may be returned as well if the server denies caller access based on its permission level?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org