如何通过改造来满足多种API终点? [英] How to address multiple API end points using Retrofit?

查看:178
本文介绍了如何通过改造来满足多种API终点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Andr​​oid项目,我用下面的改造 ApiModule 对于一个 API终点。请注意,我用匕首以注入依赖。

In my Android project I am using the following Retrofit ApiModule for one API end point. Please note, I use Dagger for injecting dependencies.

@Module(
        complete = false,
        library = true
)
public final class ApiModule {

    public static final String PRODUCTS_BASE_URL = "https://products.com";

    @Provides
    @Singleton
    Endpoint provideEndpoint() {
        return Endpoints.newFixedEndpoint(PRODUCTS_BASE_URL);
    }

    @Provides
    @Singleton
    ObjectMapper provideObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setPropertyNamingStrategy(
            PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
        return objectMapper;
    }

    @Provides
    @Singleton
    RestAdapter provideRestAdapter(
        Endpoint endpoint, ObjectMapper objectMapper) {
        return new RestAdapter.Builder()
                .setLogLevel(RestAdapter.LogLevel.NONE)
                .setEndpoint(endpoint)
                .setConverter(new JacksonConverter(objectMapper))
                .build();
    }

    @Provides
    @Singleton
    ProductsService provideProductsService(RestAdapter restAdapter) {
        return restAdapter.create(ProductsService.class);
    }

}

现在,有另一个API (如http://subsidiaries.com),我想与沟通。是否有可能延长定 ApiModule 同时重用的 ObjectMapper RestAdapter ?或者我应该不会延长呢?我已经尝试过复制的模块。但是,这涉及到我要重复端点 ObjectMapper 和...的 RestAdapter 有一个私人构造器 - 所以我不能

Now, there is another API (e.g. "http://subsidiaries.com") which I want to communicate with. Is it possible to extend the given ApiModule while reusing the ObjectMapper and the RestAdapter? Or should I not extend it? I already tried to duplicate the module. But this involves that I have to duplicate the Endpoint, ObjectMapper and ... the RestAdapter has a private contructor - so I can't.

推荐答案

我想你可以与注释:

@Module(
        complete = false,
        library = true
)
public final class ApiModule {

    public static final String PRODUCTS_BASE_URL = "https://products.com";
    public static final String SUBSIDIARIES_BASE_URL = "https://subsidiaries.com";

    public static final String PRODUCTS = "products";
    public static final String SUBSIDIARIES = "subsidiaries";

    @Provides
    @Singleton
    @Named(PRODUCTS)
    Endpoint provideProductsEndpoint() {
        return Endpoints.newFixedEndpoint(PRODUCTS_BASE_URL);
    }

    @Provides
    @Singleton
    @Named(SUBSIDIARIES)
    Endpoint provideSubsidiariesEndpoint() {
        return Endpoints.newFixedEndpoint(SUBSIDIARIES_BASE_URL);
    }

    @Provides
    @Singleton
    ObjectMapper provideObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setPropertyNamingStrategy(
            PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
        return objectMapper;
    }

    @Provides
    @Singleton
    @Named(PRODUCTS)
    RestAdapter provideProductsRestAdapter(@Named(PRODUCTS) Endpoint endpoint, ObjectMapper objectMapper) {
        return newRestAdapterBuilder(objectMapper)
                .setEndpoint(endpoint)
                .build();
    }

    @Provides
    @Singleton
    @Named(SUBSIDIARIES)
    RestAdapter provideSubsidiariesRestAdapter(@Named(SUBSIDIARIES) Endpoint endpoint, ObjectMapper objectMapper) {
        return newRestAdapterBuilder(objectMapper)
                .setEndpoint(endpoint)
                .build();
    }

    @Provides
    @Singleton
    @Named(PRODUCTS)
    ProductsService provideProductsService(@Named(PRODUCTS) RestAdapter restAdapter) {
        return restAdapter.create(ProductsService.class);
    }

    @Provides
    @Singleton
    @Named(SUBSIDIARIES)
    ProductsService provideSubsidiariesService(@Named(SUBSIDIARIES) RestAdapter restAdapter) {
        return restAdapter.create(ProductsService.class);
    }

    private RestAdapter.Builder newRestAdapterBuilder(ObjectMapper objectMapper) {
        return new RestAdapter.Builder()
                       .setLogLevel(RestAdapter.LogLevel.NONE)
                       .setConverter(new JacksonConverter(objectMapper));
    }
}

现在到处都在那里你注入 ProductsService 您需要任何注释与 @Named(产品)的依赖 @Named(子公司),这取决于变体需要。而不是 @Named 注释当然,你也可以创建自己的自定义注释和使用它们。请参见这里下的预选赛。

Now everywhere where you inject ProductsService you need to either annotate the dependency with @Named(PRODUCTS) or @Named(SUBSIDIARIES), depending on which variant you need. Of course instead of the @Named annotations you could also create your own, custom annotations and use them. See here under "Qualifiers".

要扁平化你的模块了一下,你可以将创建RestAdapters进入提供服务*()方法和摆脱提供* RestAdapter()的方法。除非你需要的RestAdapters作为模块之外的依赖,当然。

To flatten your module a bit you could move the creation of the RestAdapters into the provide*Service() methods and get rid of the provide*RestAdapter() methods. Unless you need the RestAdapters as a dependency outside of the module, of course.

这篇关于如何通过改造来满足多种API终点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆