kamikat / moshi-jsonapi

JSON API v1.0 Specification in Moshi.
MIT License
156 stars 34 forks source link

How can I integrate this with Retrofit? #2

Closed ericntd closed 8 years ago

kamikat commented 8 years ago

Add following dependency:

compile 'com.squareup.retrofit2:converter-moshi:2.0.2'

Setup Retrofit service factory:

Converter.Factory moshiConverterFactory = MoshiConverterFactory.create(
        new Moshi.Builder()
                .add(JsonApiFactory.create(/* ... */))
                .build());
Retrofit retrofit = new Retrofit.Builder()
        // ...
        .addConverterFactory(moshiConverterFactory)
        .build();

Add a service interface:

public interface Api {

    @GET("users/{id}")
    Call<Document> queryUser(@Path("id") String id);

    @POST("sessions")
    Call<Document> createSession(@Body Document session);

}

Create service instance:

Api service = retrofit.create(Api.class);
ericntd commented 8 years ago

Sorry @kamikat but I ended up with a bunch of moe.banana.jsonapi.Resource objects, I thought I would automatically get my Product3 objects?

Am I supposed to extend your moe.banana.jsonapi.Resource class?

Product3.java

@AttributesObject(type = "products")
public class Product3 {
    @Json(name="slug-url") private String slugUrl;
    private String name;
    @Json(name="image-urls") private List<String> imageUrls = new ArrayList<String>();
    private Integer price;
    @Json(name="sold-out") private Boolean soldOut;
    @Json(name="variants-count") private Integer variantsCount;
    private String description;
    private String benefits;
    private String application;
    private String ingredients;
    @Json(name="option-type-category") private String optionTypeCategory;
}

Product3Api.java

public interface Product3Api {
    public static final Product3Api service = SdsRestClient.retrofit3.create(Product3Api
            .class);

    @GET("products")
    Call<Document> listProducts();
}

SdsRestClient.java

public static Moshi moshi = new Moshi.Builder()
            .add(JsonApiFactory.create(Product3.class)) // Setup JSON API adapter factory
            .build();
    public static Converter.Factory moshiConverterFactory = MoshiConverterFactory.create(moshi);
    public static final Retrofit retrofit3 = new Retrofit.Builder()
            .addConverterFactory(moshiConverterFactory)
            .baseUrl(STAGING)
            .build();

How I use Retrofit:

Call<Document> call = Product3Api.service.listProducts();
            call.enqueue(new Callback<Document>() {
                @Override
                public void onResponse(Call<Document> call, Response<Document> response) {
                    int statusCode = response.code();
                    Log.i(TAG, "response: " + response.body());
                    Document resp = response.body();
                    for (Resource resource : resp.data()) {
                        Log.i(TAG, resource.id());
                    }
                }

                @Override
                public void onFailure(Call<Document> call, Throwable t) {
                    // Log error here since request failed
                    Log.e(TAG, "", t);
                }
            });

The JSON response for my product listing: screen shot 2016-07-21 at 12 20 10 am

kamikat commented 8 years ago

Resource is designed not inheritable (a default access of constructor function prevents the abstract class from being inherited outside the package).

It's a pity that as of 1.x the library only supports serialize/deserialize of json-api formatted data and lacks feature to resolve Document or Relationships. Could you please open another issue about the question and let's set it to milestone 2.0