opengeospatial / ogcapi-common

OGC API - Common provides those elements shared by most or all of the OGC API standards to ensure consistency across the family.
https://ogcapi.ogc.org/common
Other
45 stars 14 forks source link

How does a client know, which of the list of supported resources, is suitable for POST/PUT (insert/update)? #179

Open pvretano opened 4 years ago

pvretano commented 4 years ago

Most servers advertise in the conformance document which feature formats they support (e.g. GeoJSON, GML, etc.). However, not all formats (e.g. HTML) are a suitable representations for use with a HTTP POST. How does a client know which formats may be used with a POST/PUT? One way is to use the OpenAPI document but it seems like a pretty heavy lift to make clients (especially ones that don't use OpenAPI-base tool chains) have to read the OpenAPI document to figure this out. Would another approach we of value? Perhaps some variant of OPTIONS or something similar to /queryables or perhaps some form of parameterized conformance document that crosswalks the format-based conformance classes with the methods they support (e.g. GeoJSON with GET,PUT,POST).

jerstlouis commented 4 years ago

Another approach (in addition to OpenAPI document?) would be super valuable.

+1 for not requiring an OpenAPI parsing to determine the validity or parameters of any operation, as it would put some development frameworks / methodologies at a great disadvantage.

cmheazel commented 4 years ago

How about an API Description element with one entry for each HTTP verb supported for the described resource? Each "verb" could have an additional set of metadata describing parameters, response schema, etc. And what better time to try it out than a sprint?

cportele commented 4 years ago

Features API SWG meeting 2020-10-12: Investigate, if OPTIONS can address this. We don't want to invent a new API definition grammar that is basically a stripped-down OpenAPI definition. @pvretano will look at how OPTIONS as specified in the HTTP RFC can address the need.

pomakis commented 4 years ago

In my experience, an HTTP OPTIONS request is a great way for a client to determine which HTTP methods are available at a particular endpoint. In fact, it's exactly what the HTTP OPTIONS method is for. We have implemented this for many of the endpoints on our test "OGC API" server at "https://test.cubewerx.com/cubewerx/cubeserv/demo/ogcapi/Daraa".

E.g., an HTTP OPTIONS request to

https://test.cubewerx.com/cubewerx/cubeserv/demo/ogcapi/Daraa/collections

returns

Allow: GET,HEAD,OPTIONS

while an HTTP OPTIONS request to

https://test.cubewerx.com/cubewerx/cubeserv/demo/ogcapi/Daraa/styles

returns

Allow: GET,HEAD,POST,OPTIONS

This is sensitive to identity as well, so clients will get an "Allow" response header that's specific to them based on the access-control rules of the server.

Of course our OpenAPI document at "https://test.cubewerx.com/cubewerx/cubeserv/demo/ogcapi/Daraa/api" also lists the HTTP methods available at each endpoint, and that too is sensitive to identity. But as stated in a previous comment, it would be a rather heavyweight thing for a client to look up. Whereas an HTTP OPTIONS request is a well-established single-packet few-millisecond request.

cportele commented 3 years ago

@pomakis - Agreed. However, there is one aspect of the original comment that the standard OPTIONS does not address:

How does a client know which formats may be used with a POST/PUT?

pomakis commented 3 years ago

@cportele - True.

One possible solution is to state that the OPTIONS response headers can contain an HTTP Accept header (as specified in RFC 7231 section 5.3) indicating what the endpoint can accept. The HTTP Accept header is typically used in a request to indicate what the client (requester) is willing to accept, but I see no reason it couldn't be used the other way around.

E.g., an HTTP OPTIONS request to

  https://test.cubewerx.com/cubewerx/cubeserv/demo/ogcapi/Daraa/styles

could return

  Allow: GET,HEAD,POST,OPTIONS
  Accept: application/vnd.ogc.sld+xml

Just a thought.

cmheazel commented 3 years ago

One goal of OGC Web APIs is to align with main-stream IT. If a client does not want to parse the OpenAPI document, then they should rely on the HTTP protocol. We should not invent our own non-standard solution.

RFC 7231 states that "A server generating a successful response to OPTIONS SHOULD send any header fields that might indicate optional features implemented by the server and applicable to the target resource". As I read this, the server should include an "accepts" header and all valid values for that header. So main-stream IT provides us with a solution and this issue can be closed.

jerstlouis commented 3 years ago

@cmheazel I think the solution proposed by @pomakis above in part relates to the discussion in https://github.com/opengeospatial/ogcapi-common/issues/160 , as even with only GET support, if I understand correctly, it would provide a mechanism for the server to list all supported media-types for a given resource path. Would there be a way to distinguish between the formats acceptablle for each method (as they may differ)?

As I read this, the server should include an "accepts" header and all valid values for that header

Is this the singular "Accept:" as in Keith's example above? Accept: application/vnd.ogc.sld+xml

Does any requirement, recommendation or non-normative guidance need to be clarified in Part 1: Core before this issue can be closed?

pomakis commented 3 years ago

@jerstlouis wrote:

Would there be a way to distinguish between the formats acceptablle for each method (as they may differ)?

I think that's a bit beyond what a simple Accept-header mechanism can provide. I envision this header (in an OPTIONS response) indicating only what the endpoint can accept in a POST or PUT body. It's not strictly necessary to list all of the formats that it can serve in response to a GET operation. Firstly, the set of hypermedia links that the client navigates through to get to the endpoint typically provides specific links to the various available formats. Also, the resource itself can sometimes provide a set of "alt" links. Finally, and perhaps most importantly, remember that "Accept" is primarily defined as a request header. In most cases, therefore, a client shouldn't care what the available choices are when making a GET request. It can just list what its preferences are as per RFC 7231 section 5.3.2.

m-mohr commented 3 years ago

I'm not sure whether this mirrors all use cases (probably not), but in STAC we use a method property in the links, e.g.

{
  "href": "https://example.com/search",
  "method": "GET"
}

GET is the default for method, so the "method": "GET" you'd be omitted and I've just added it for demonstration purposes.

If there's also support for POST, you would add another link:

{
  "href": "https://example.com/search",
  "method": "POST"
}

OPTIONS is surely a good option as it's just HTTP and Browsers request it anyway, but I'm not sure how easy it is to get the result without making a second request via your preferred JS library for HTTP requests. And in most other environments you need a separate HTTP request.

cportele commented 3 years ago

If we want to extend the link object, then we should consider to follow the HTTP Link Hints proposal: https://mnot.github.io/I-D/link-hint/

m-mohr commented 3 years ago

Interesting, @cportele. Thanks for the heads-up, we should also take that into consideration in STAC - and I think we can still do so without breaking too much.