MarkoMilos/jsonapi

What do I pass for type?

mdance opened this issue · 3 comments

I'm following the README documentation and I'm confused about what to pass for type:

Create adapter for Document type:

val adapter = moshi.adapter<Document

>(type)

val type = Document::class.java
val adapter = moshi.adapter<Document>(type)

complains with:
Exception in thread "main" java.lang.IllegalArgumentException: No JsonAdapter for T (with no annotations)

val type = Account::class.java
val adapter = moshi.adapter<Document>(type)

Seems to work, but when I run:

val document = adapter.fromJson(response)

It crashes with:

Exception in thread "main" jsonapi.JsonFormatException: A resource identifier MUST contain non-null/non-empty type member but it was not found on path: $

Here is the jsonapi body:

{
  "jsonapi": {
    "version": "1.0",
    "meta": {
      "links": {
        "self": {
          "href": "http://jsonapi.org/format/1.0/"
        }
      }
    }
  },
  "data": [
    {
      "type": "account--bank_account",
      "id": "redacted",
      "links": {
        "self": {
          "href": "redacted"
        }
      },
      "attributes": {
        "drupal_internal__id": 1,
        "name": "redacted",
        "status": true,
        "field_balance": 0,
        "field_hidden": false,
        "field_weight": 0
      },
      "relationships": {
        "field_account_status": {
          "data": {
            "type": "taxonomy_term--account_status",
            "id": "redacted",
            "meta": {
              "drupal_internal__target_id": 1
            }
          },
          "links": {
            "related": {
              "href": "redacted"
            },
            "self": {
              "href": "redacted"
            }
          }
        },
        "field_account_type": {
          "data": {
            "type": "taxonomy_term--account_type",
            "id": "redacted",
            "meta": {
              "drupal_internal__target_id": 1
            }
          },
          "links": {
            "related": {
              "href": "redacted"
            },
            "self": {
              "href": "redacted"
            }
          }
        },
        "field_currency": {
          "data": {
            "type": "taxonomy_term--currency",
            "id": "redacted",
            "meta": {
              "drupal_internal__target_id": 1
            }
          },
          "links": {
            "related": {
              "href": "redacted"
            },
            "self": {
              "href": "redacted"
            }
          }
        }
      }
    }
  ],
  "included": [
    {
      "type": "taxonomy_term--account_status",
      "id": "redacted",
      "links": {
        "self": {
          "href": "redacted"
        }
      },
      "attributes": {
        "drupal_internal__tid": 1,
        "status": true,
        "name": "Active",
        "description": null,
        "weight": 0
      }
    },
    {
      "type": "taxonomy_term--account_type",
      "id": "redacted",
      "links": {
        "self": {
          "href": "redacted"
        }
      },
      "attributes": {
        "drupal_internal__tid": 1,
        "status": true,
        "name": "Deposit",
        "description": null,
        "weight": 0
      }
    },
    {
      "type": "taxonomy_term--currency",
      "id": "redacted",
      "links": {
        "self": {
          "href": "redacted"
        }
      },
      "attributes": {
        "drupal_internal__tid": 1,
        "status": true,
        "name": "redacted",
        "description": null,
        "weight": 1,
        "field_currency_code": "redacted"
      }
    }
  ],
  "links": {
    "first": {
      "href": "redacted"
    },
    "next": {
      "href": "redacted"
    },
    "prev": {
      "href": "redacted"
    },
    "self": {
      "href": "redacted"
    }
  }
}

It is not possible to pass in plain Document type since Document<T> is generic.

For example, if you have a document of an article (standard example) it is not possible to pass the type of the Document like this

val type = Document::class.java

Nor you can do

val type = Article::class.java

Instead, you need to pass parameterized type

// Create a type for Document<Article>
val type = Types.newParameterizedType(Document::class.java, Article::class.java)
val articleAdapter: JsonAdapter<Document<Article>> = moshi.adapter(type)

In case you have a collection of articles then you can do it like this:

// Create a type for Document<List<Article>>
val type = Types.newParameterizedType(Document::class.java, Types.newParameterizedType(List::class.java, Article::class.java))
val articleAdapter: JsonAdapter<Document<List<Article>>> = moshi.adapter(type)

Thanks for your help, I've gotten things working