• Stars
    star
    156
  • Rank 238,313 (Top 5 %)
  • Language
    Java
  • License
    MIT License
  • Created over 8 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

JSON API v1.0 Specification in Moshi.

moshi-jsonapi

Build Status Coverage Status Download

Java implementation of JSON API specification v1.0 for moshi.

Getting Started

JsonAdapter.Factory jsonApiAdapterFactory = ResourceAdapterFactory.builder()
        .add(Article.class)
        .add(Person.class)
        .add(Comment.class)
        // ...
        .build();
Moshi moshi = new Moshi.Builder()
        .add(jsonApiAdapterFactory)
        // ...
        .build();

You're now ready to serialize/deserialize JSON API objects with cool Moshi interface!

String json = "...";
ArrayDocument<Article> articles = moshi.adapter(Document.class).fromJson(json).asArrayDocument();
for (Article article : articles) {
  System.out.println(article.title);
}

Usage

Resource Object

Extend a Resource class to create a model for resource object.

@JsonApi(type = "people")
class Person extends Resource {
    @Json(name="first-name") String firstName;
    @Json(name="last-name") String lastName;
    String twitter;
}

@JsonApi(type = ...) annotation identifies each model by type as is mentioned in specification.

Relationships

There are two kinds of relationship defined in JSON API specification. Defining these relationship in resource object is quite simple:

@JsonApi(type = "articles")
public class Article extends Resource {
    public String title;
    public HasOne<Person> author;
    public HasMany<Comment> comments;
}

Relationships can be resolved to resource object in a Document:

Person author = article.author.get(article.getDocument());

You can use Resource.getDocument() to access the Document object the Resource be added/included in. Further more, with a little bit encapsulation:

@JsonApi(type = "articles")
public class Article extends Resource {
    private String title;
    private HasOne<Person> author;
    private HasMany<Comment> comments;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Person getAuthor() {
        return author.get(getDocument());
    }

    public List<Comment> getComments() {
        return comments.get(getDocument());
    }
}

Document

Document interfaces denotes a JSON API document, document object contains one of the following attributes:

  • data the primary data, can be null, resource object or array of resource object
  • error error object
  • meta

To keep consistency with the specification, moshi-jsonapi implements ArrayDocument<T> and ObjectDocument<T>. Document object can be converted with Document.<T>asXDocument() function.

ObjectDocument<Article> document = new ObjectDocument<>();
document.set(article);
document.addInclude(author);

// Serialize
System.out.println(moshi.adapter(Document.class).toJson(document));
// => {
//      data: { "type": "articles", "relationships": { "author": { "data": "type": "people", id: "1" } } },
//      included: [
//        { "type": "people", "attributes": { "first-name": "Yuki", "last-name": "Kiriyama", "twitter": "kamikat_bot" } }
//      ]
//    }

// Deserialize
Document document2 = adapter.fromJson(...);
ObjectDocument<Article> document3 = document2.asObjectDocument();
assert document3.get() instanceof Article
assert document3.get().getDocument() == document3

The linkage (relationship) of a resource object is resolved in document of the resource object (check Resource.getDocument()).

Default Resource Type

Create a default typed class to have all unknown type parsed in the class to avoid deserialization error processing unknown type of resource.

@JsonApi(type = "default")
class Unknown extends Resource {
    // nothing...
}

meta/links/jsonapi Properties

You'd like to access meta/links/jsonapi value on Document for example.

Document document = ...;
document.getMeta() // => JsonBuffer

As meta and links can contain a variant of objects, they are not been parsed when access with getMeta and getLinks. You will get a JsonBuffer and you're expected to implement your JsonAdapter<T> to read/write these objects.

Retrofit

Retrofit extension library (see following section) provides JsonApiConverterFactory to get integrate with Retrofit 2. Here's an example:

Retrofit retrofit = new Retrofit.Builder()
        // ...
        .addConverterFactory(JsonApiConverterFactory.create(moshi))
        .build()
retrofit.create(MyAPI.class);

And MyAPI interface:

public interface MyAPI {

    @GET("posts")
    Call<Post[]> listPosts();

    @GET("posts/{id}")
    Call<Post> getPost(@Path("id") String id);

    @GET("posts/{id}/comments")
    Call<List<Comment>> getComments(@Path("id") String id);

    @POST("posts/{id}/comments")
    Call<Document> addComment(@Path("id") String id, @Body Comment comment);

    @GET("posts/{id}/relationships/comments")
    Call<ResourceIdentifier[]> getCommentRels(@Path("id") String id);
}

Note that the body can either be serialized/deserialized to resource object or document object with additional information.

Download

In gradle build script:

repositories {
    jcenter()
}

dependencies {
    implementation 'com.squareup.moshi:moshi:1.4.0'                        // required, peer dependency to moshi
    implementation 'moe.banana:moshi-jsonapi:<version>'                    // required, core library
    implementation 'moe.banana:moshi-jsonapi-retrofit-converter:<version>' // optional, for retrofit
}

For library version >= 3.5, moshi is removed from runtime dependencies of the library to become a peer dependency.

Use snapshot version:

repositories {
    maven { url "https://jitpack.io" }
}

dependencies {
    implementation 'com.squareup.moshi:moshi:1.4.0'
    implementation 'moe.banana:moshi-jsonapi:master-SNAPSHOT'
}

NOTE: It's necessary clean gradle library cache to access the latest snapshot version.

Proguard Guide

For moshi-jsonapi:

-keepattributes Signature
-keepclassmembers public abstract class moe.banana.jsonapi2.** {
    *;
}

For moshi, if you use a custom JSON adapter (e.g. for Enum types):

-keepclassmembers class ** {
    @com.squareup.moshi.FromJson *;
    @com.squareup.moshi.ToJson *;
}

Supported Features

Feature Supported Note
Serialization Yes
Deserialization Yes
Custom-named fields Yes With @Json
Top level errors Yes
Top level metadata Yes
Top level links Yes
Top level JSON API Object Yes
Resource metadata Yes
Resource links Yes
Relationships Yes HasOne and HasMany
Inclusion of related resources Yes
Resource IDs Yes

Migration Note for 3.4 and 3.5

Release 3.4 removed type parameter from Document object which can break your code. Please replace the type declaration with ObjectDocument<T> or ArrayDocument<T> if you insist that.

Release 3.5 changes the dependency to moshi from runtime dependency to compile-only dependency, which means moshi-jsonapi does no longer includes moshi as a dependency for your project. And you need to add moshi to the dependencies of the project manually.

Migration from 2.x to 3.x

3.x supports all features supported by JSON API specification. And the interface changed a lot especially in serialization/deserialization. More object oriented features are added to new API. If you're using the library with Retrofit, migration should be a lot easier by using a special Converter adapts Document<Article> to Article[] and backward as well (see retrofit section). Migration should be easy if you use latest 2.x API with some OO features already available. Otherwise, it can take hours to migrate to new API.

Migration from 1.x to 2.x

2.x abandoned much of seldomly used features of JSON API specification and re-implement the core of JSON API without AutoValue since AutoValue is considered too verbose to implement a clean model.

And the new API no longer requires a verbose null check since you should take all control over the POJO model's nullability check.

Another major change is that the new API is not compatible with AutoValue any more. Means that one have to choose 1.x implementation if AutoValue is vital to bussiness logic.

License

(The MIT License)

More Repositories

1

tttfi

Middleware for IFTTT.
JavaScript
348
star
2

bilibili-get

Bilibili video downloader.
JavaScript
185
star
3

jekyll-theme-kagami

Simple and clean Jekyll theme compatible with GitHub Pages.
SCSS
150
star
4

toast-compat

Toast notification polyfill.
Java
56
star
5

52g

Index leaked password data with bloom filter.
C++
50
star
6

cpktools

cpk file tools and text extraction tools for translation works on ε‚γ‚γŒγ‚Šγƒγƒͺケーン
Python
49
star
7

onscripter

Mirror of onscripter by ogapee
C++
32
star
8

feedo

RSS reader for automation.
Python
18
star
9

flvcopycat

Joining flv files with same options (normally splitted by video sites) together losslessly
Python
18
star
10

bilibili-playurl

Get playurl from cid.
JavaScript
16
star
11

co-router

Benefit from generator on express router.
JavaScript
11
star
12

o3o_bot

Kaomoji on Telegram Bot API
Go
11
star
13

ping-chart

Ping statistics in ASCII chart.
Shell
10
star
14

openwrt-dirtydns

Simple DNS forwarder for OpenWRT.
Shell
8
star
15

ONScripter-SAO

Android Based UI Product take SAO(Animation) as prototype
C
6
star
16

XGIMI-Z6-Polar-Toybox

Customize XGIMI Z6 Polar (synsepalum_R) device.
Shell
5
star
17

abt

BitTorrent workflow with aria2.
Python
5
star
18

fontconfig

fontconfig configuration
5
star
19

vimrc

My $HOME/.vim with Git & Pathogen
Vim Script
5
star
20

mm.io

Simple demonstration of MVP with Dagger2/Android Data Binding Library and RxJava
Java
4
star
21

OreoTintRemover

Remove annoying color tint from lock-screen and notification background.
Java
4
star
22

DidiTech2016

Solution to DidiTech2016 problem using Random Forest.
Python
4
star
23

Courier-Typewritter-Fonts

Monospace font based on Courier 10 Pitch by thynson
4
star
24

dagger2-android-example

IoC on Android done right with Dagger2.
Java
4
star
25

squel-sugar

Several syntactic sugar extension to https://hiddentao.github.io/squel/ API
JavaScript
3
star
26

kisstudou

Project to download and auto convert web video from tudou,youku,bilibili
Python
3
star
27

onscripter-cn

onscripter for android forked from natdon-san
C
2
star
28

docker-wine-py

Python 2.7 for Windows in Docker.
1
star
29

iona

Lightweight library for creating interactive docs.
JavaScript
1
star
30

haskell-trains

Solutions to Haskell problems on Codewars.
Haskell
1
star
31

grunt-boilerplate

Boilerplate for grunt based frontend(f2e) workflow
JavaScript
1
star
32

onscripter_android

C
1
star
33

octrello

Integrate Trello with GitHub.
JavaScript
1
star
34

mxnet-onbuild

Automated MXNet build.
Shell
1
star