Repository: jokiefer/drf-json-api-atomic-operations (language: python)

Issue:
Media Type value is incorrect
The media type

```py
ATOMIC_MEDIA_TYPE = 'vnd.api+json;ext="https://jsonapi.org/ext/atomic'
```

is incorrect. This value forces the client to provide the header `accept: vnd.api+json;ext="https://jsonapi.org/ext/atomic` which is unexpected. Notice the missing `"`.

The user should be able to provide `accept: vnd.api+json;ext="https://jsonapi.org/ext/atomic"` but this currently results in a 406 error.

In addition, it would be helpful to note that the usual value for the accept header `*/*` is not valid for this view. The client must provide the `ext` parameter.


Discussion / hints:
After crawling the json:api spec v1.1 again, it seems to me, that the correct naming would be `vnd.api+json; ext="https://jsonapi.org/ext/atomic"`. Notice the missing space-separated (U+0020 SPACE, “ “) described in [5.4](https://jsonapi.org/format/#media-type-parameter-rules). The [example](https://jsonapi.org/ext/atomic/#auto-id-creating-resources) leads in to a wrong documented content-type. The Content-Type is not explicit defined inside the extension docs. It also not needed, cause 5.4 from the v1.1 specs is well defined for this case i think.

@sliverc am i right at this point? 

> In addition, it would be helpful to note that the usual value for the accept header */* is not valid for this view. The client must provide the ext parameter.

I do not handle the accept header in my package explicitly. So it seems not a problem of this package.
Thanks for the relevant spec sections, I didn't find those.

As for the compatibility with `accept: */*`: The revelant code is in [django-rest-framework](https://github.com/encode/django-rest-framework/blob/master/rest_framework/utils/mediatypes.py#L53). I'm not sure if the behavior is desired or not; The logic requires the client to provide all the parameters (`ext="foo"`) of the renderer _before_ it considers the wildcards.

I can open a bug there if we think this behavior isn't desired, but either way it seems like it would be helpful to document in this library because most developers won't have had to think about the accept header until using this library.
I am bit confused about the space. In the spec 5.4 it states there needs to be a space when there is more than one ext or profile defined. In the example of 5.4.1 there is clearly a space although there is only one ext. But in the atomic documentation there is no space. Best ask upstream what the right content type is, as this is certainly a bug in the specification one way or the other.

In terms of Accept  `*/*` have a look at the [DRF documentation](https://www.django-rest-framework.org/api-guide/renderers/#ordering-of-renderer-classes) where it explains how `*/*` is interpreted.
> If a client underspecifies the representations it can accept, such as sending an Accept: */* header, or not including an Accept header at all, then REST framework will select the first renderer in the list to use for the response

This makes it seem like the behavior i found was undesired. I started [a discussion](https://github.com/encode/django-rest-framework/discussions/9564) about it.
wrote [an issue](https://github.com/json-api/json-api/issues/1770) about our question regarding the media type syntax

Fix patch:
diff --git a/atomic_operations/consts.py b/atomic_operations/consts.py
index c36a624..aa76ccd 100644
--- a/atomic_operations/consts.py
+++ b/atomic_operations/consts.py
@@ -1,4 +1,4 @@
 ATOMIC_OPERATIONS = "atomic:operations"
 ATOMIC_RESULTS = "atomic:results"
-ATOMIC_MEDIA_TYPE = 'vnd.api+json;ext="https://jsonapi.org/ext/atomic'
+ATOMIC_MEDIA_TYPE = 'vnd.api+json;ext="https://jsonapi.org/ext/atomic"'
 ATOMIC_CONTENT_TYPE = f'application/{ATOMIC_MEDIA_TYPE}'


Test patch:
diff --git a/tests/test_views.py b/tests/test_views.py
index 83ce388..b78efd4 100644
--- a/tests/test_views.py
+++ b/tests/test_views.py
@@ -21,6 +21,29 @@ def setUp(self):
 
         self.maxDiff = None
 
+    def test_content_type_extension(self):
+        """Test that the correct content type is accepted
+        
+        The media type and parameters are defined at https://jsonapi.org/ext/atomic. This tests
+        hardcodes the value to separate the test from the library's constants.
+        
+        """
+        operations = []
+
+        data = {
+            ATOMIC_OPERATIONS: operations
+        }
+
+        response = self.client.post(
+            path="/",
+            data=data,
+            content_type='application/vnd.api+json; ext="https://jsonapi.org/ext/atomic"',
+
+            **{"HTTP_ACCEPT": 'application/vnd.api+json; ext="https://jsonapi.org/ext/atomic"'}
+        )
+
+        self.assertNotEqual(406, response.status_code)  # 406 Not Acceptable
+
     def test_view_processing_with_valid_request(self):
         operations = [
             {