#json-api #deserialize #macro #document #field #rename #relationship

macro jsonapi_deserialize_derive

Macro implemention of #[derive(JsonApiDeserialize)]

6 stable releases

1.2.0 Oct 31, 2024
1.1.1 Oct 31, 2024
1.1.0 Oct 30, 2024
1.0.2 Oct 30, 2024

#11 in #relationship

47 downloads per month
Used in jsonapi_deserialize

BSD-2-Clause

14KB
188 lines

JSON-API 1.1 Deserialization

Release

A simple library to facilitate deserialization of JSON-API responses into structs. In contrast to existing libraries this one specifically focuses on consumption of payloads, rather than generation. The reasons for this are manifold, but primarily is there a large contrast between consumption and generation.

When consuming payloads from an API, you will like receive several included resources several times. While JSON-API does already take care of de-duplication, inlining those resources becomes tricky. On the consuming side you additionally might only have a sparse set of data, which would not necessarily match a generating model.

Usage

This library exports a single function deserialize_json_api_document(). Simply pass in a 6str of your JSON and you are good to go. The type you are deserializing to must implement the JsonApiDeserialize trait. For your convenience the library also exports a derive macro with the same name.

When using the macro, you must have an id field on your struct with a String type. Any other fields are considered either attributes or relationships.

All attributes in a struct must implement Serde's Deserialize trait.

Resource type

By default, the resource type for a struct will be derived from the struct name, converted to snake_case. To override this, you can annotate the struct the following way:

#[json_api(resource_type = "foo")]
struct Bar;

Field renaming

Without further configuration, the library follows the JSON-API recommendation that all fields in JSON should be camel-cased. You can change this behavior with the rename_all attribute, similar to Serde. You can choose between camel_case, pascal_case and snake_case.

Additionally you can also rename individual fields with the rename attribute.

Relationships

Unless specified otherwise, a field is always an attribute. To specify a field as a relationship, set the relationship attribute to one of the following values:

  • single: a single resource or reference
  • optional: an optional resource or reference
  • multiple: one or more resources or references

References must be typed as one of the following three types:

  • Reference
  • Option<Reference>
  • Vec<Reference>.

Resources which are included in the document must be typed as one of the following three types:

  • Arc<T>
  • Option<Arc<T>>
  • Vec<Arc<T>>

The reason for the Arc is because the same resource can be shared across multiple relationships.

Error handling

There are two possible failure cases when calling deserialize_json_api_document() which can result in an error:

  • Error::DeserializeError(DeserializeError): There was a syntactic error while parsing the document
  • Error::DocumentError(Vec<DocumentError>): The document contains errors instead of data

The first kind of error either means that your structs do not match what's returned or that the server generated garbage. The second kind means that either there was a server error or that your request had errors. You can distinguish this based on whether the HTTP response code was in the 4xx or 5xx range.

Examples

Have a look at the tests in the test_suite folder. Those are examples covering all current use-cases.

Dependencies

~0.6–1MB
~23K SLoC