SIDN / ietf-epp-restful-transport

RESTful transport for EPP
Other
3 stars 4 forks source link

Purpose of <epp><command><{command}> xml structure in POST body #51

Open pawel-kow opened 6 months ago

pawel-kow commented 6 months ago

In 9.5.1. Example Domain Create request:

C: POST /repp/v1/domains HTTP/2
C: Host: repp.example.nl
C: Authorization: Bearer <token>
C: Accept: application/epp+xml
C: Content-Type: application/epp+xml
C: REPP-Svcs: urn:ietf:params:xml:ns:domain-1.0
C: Accept-Language: en
C: Content-Length: 220
C:
C:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
C:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
C:  <command>
C:    <create>
C:      <domain:create
C:       xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
C:        <domain:name>example.nl</domain:name>
C:        <!-- The rest of the request is omitted here -->
C:      </domain:create>
C:    </create>
C:    <clTRID>ABC-12345</clTRID>
C:  </command>
C:</epp>

Question - what is the added value of <{command}> envelope, when this is actually duplicated by resource path /domains and the http verb ( command)? For clTRID, which is enclosed in this structure there is a defined header REPP-Cltrid.

structure looks like still rpc format, not a resource representation. Duplication of information between the resource URI and resource content will lead to a new class of errors, when those two would not match. Alternative: ``` C: POST /repp/v1/domains HTTP/2 C: Host: repp.example.nl C: Authorization: Bearer C: Accept: application/epp+xml C: Content-Type: application/epp+xml C: REPP-Svcs: urn:ietf:params:xml:ns:domain-1.0 C: REPP-Cltrid: ABC-12345 C: Accept-Language: en C: Content-Length: 220 C: C: C: C: example.nl C: C: ``` The question has relevance, if JSON representation is considered, then such response would look like this: ``` { "@xmlns:domain": "urn:ietf:params:xml:ns:domain-1.0", "domain:name": "example.com", "domain:period": { "@unit": "y", "#text": "2" }, "domain:ns": { "domain:hostObj": [ "ns1.example.net", "ns2.example.net" ] }, "domain:registrant": "jd1234", "domain:contact": [ { "@type": "admin", "#text": "sh8013" }, { "@type": "tech", "#text": "sh8013" } ], "domain:authInfo": { "domain:pw": "2fooBAR" } } ``` Or even, assuming the namespace "domain" can be also derived from the resource path: ``` { "name": "example.com", "period": { "@unit": "y", "#text": "2" }, "ns": { "hostObj": [ "ns1.example.net", "ns2.example.net" ] }, "registrant": "jd1234", "contact": [ { "@type": "admin", "#text": "sh8013" }, { "@type": "tech", "#text": "sh8013" } ], "authInfo": { "pw": "2fooBAR" } } ```
mwullink commented 5 months ago

yes there is some duplication there, but we choose to keep the elements because of the extension mechanism built into epp. see: https://datatracker.ietf.org/doc/html/rfc5730#section-2.7.1

it is possible to create a protocol and Command-Response level extension. Without the elements you may end up having multiple root elements (command + extension) and invalid xml

see the domain create + dnssec extension for example. https://datatracker.ietf.org/doc/html/rfc5910#section-5.2.1

pawel-kow commented 5 months ago

OK, this is quite problematic indeed. EPP is in this term really RPC-style and not RESTful and this legacy would be an obstacle on the way to get to real resource representation for a RESTful API.

So the question - whether this is the way, or the proposal shall indeed change the schema a bit more to have cleaner resource modelling rather than commands.

One way to do with extensions - see Afnic approach https://api-sandbox.nic.fr/api-docs/#tag/domain-registrar-controller/operation/create_11_1_1_1 extensions are a property of a resource, not a command and then encapsulated into own properties per extension to avoid naming conflicts.

As "Compatibility with existing EPP commands and corresponding request and response messages." is in the design principles then there is likely no way out here. One may question the benefit of breaking down resources URIs, with the given added complexity of superfluous identifiers, rather than just passing EPP commands RPC-style over certain controller URIs, similar to what was proposed in draft-loffredo-regext-epp-over-http.

mwullink commented 5 months ago

Took a first shot at a new xsd for REPP, to get rid of the rpc-style command structure. also gives us the chance to get rid of unused xml types defined for command such as login/logout/poll

see: https://github.com/SIDN/ietf-epp-restful-transport/blob/main/src/xml/repp-1.0.xsd for the new xsd

i also added an example xml to show how it would look. see: https://github.com/SIDN/ietf-epp-restful-transport/blob/main/src/xml/example-request.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<repp xmlns="urn:ietf:params:xml:ns:repp-1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:ietf:params:xml:ns:repp-1.0 repp-1.0.xsd">
    <request>
        <body>
            <test:hello xmlns:test="urn:ietf:params:xml:ns:test-1.0"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:ietf:params:xml:ns:test-1.0 test.xsd">
                <!-- Object-specific elements. -->
            </test:hello>
        </body>
    </request>
</repp>

the extension points a the different levels should are still supported using this new schema.

pawel-kow commented 5 months ago

@mwullink I think this might be a good middle ground. Maybe names would be something to look at to make it even less RPC. Maybe instead of sth like ...