Swagger-codegen: [JAVA] Retrofit2 Observable<Void> should be Observable<Response<Void>>

Created on 23 Sep 2017  路  18Comments  路  Source: swagger-api/swagger-codegen

Description

API calls that have no response content causes a null pointer in retrofit.

Null is not a valid element

This is currently what is produced:

  @POST("logout")
  Observable<Void> logout();

This causes the: Observable onNext to never be called

Swagger-codegen version

2.2.3

Swagger declaration file content or url
  /logout:
    post:
      operationId: logout
      responses:
        200:
          description: success
        401:
          description: 401
Command line used for generation
{
  "library": "retrofit2",
  "groupId": "com.test",
  "artifactVersion":"0.0.2",
  "invokerPackage": "com.test",
  "modelPackage": "com.test.model",
  "apiPackage": "com.test.api",
  "useRxJava2": true,
  "hideGenerationTimestamp": true
}

swagger-codegen generate -i doc/api/definitions/test.yaml -c doc/api/config/test.json -l java -o libs/api/test

Using:
Kotlin, Java, Retrofit2

Steps to reproduce
  1. generate the api
  2. subscribe to api.logout()
Related issues/PRs

Suggest a fix/enhancement

Swagger-codgen produces Observable<Void> when it should produce Observable<Response<Void>>

I found the solution here: https://stackoverflow.com/questions/41914037/rxjava2-retrofit2-handling-null-for-204-put-and-delete-requests

Java Retrofit Suggestion

Most helpful comment

I just confirmed that this still happens in v2.3.0
@wing328

All 18 comments

I tested by manually overwriting with Observable<Response<Void>> and everything works as expected.

I think it would be more clean to use Completable as the return type although Response also works.

@wing328 Any information on what swagger.yml response would lead to a Completable being generated?

Or is this not supported?

in RxJava2 Observable\

@zkdzegede sorry for late reply on this. Please kindly try the latest stable release v2.3.0. If it's still an issue, we will look into it.

It seems like v2.3.0 is not in brew...

I just confirmed that this still happens in v2.3.0
@wing328

cc @bbdouglas @JFCote @sreeshas @jfiala @lukoyanov @cbornet

I confirm this still happens in v2.3.0 too. It's a really big problem because typical DELETE or any other endpoint that returns noting just doesn't work.

We should set Completable instead of Observable<Void> as @jschoedt proposed. I tested such replacement (Observable<Void> -> Completable), works as expected.

For those who generate client out of swagger defs directly during compile time, you may want use this dirty temporary hack (Gradle):

yourSwaggerGenTask.doLast {
    // Temporary fix https://github.com/swagger-api/swagger-codegen/issues/6553
    fileTree(dir: "$buildDir/yourSwaggerGenOutputFolder", include: '**/*Api.java').each {File file ->
        String apiContent = file.getText()
        apiContent = apiContent.replaceAll("Observable<Void>", "Completable")
        apiContent = apiContent.replaceAll("import io.reactivex.Observable;",
            "import io.reactivex.Observable;import io.reactivex.Completable;")
        file.write(apiContent)
    }
}

The problem is that with Completable you lose response headers (typically the location header in a 201 created op)

Even if temporary it seems better than the current situation which is an Error since RxJava2 Observables cannot contain Void.

I think Flowables can so would it be reasonable to change it to Flowable\ I may be mistaken of course.

In general, contents are application/json which is not "streamable" so I would say Single would be better than Flowable

The problem is that with Completable you lose response headers (typically the location header in a 201 created op) @cbornet

It's the problem of all current RxJava2 endpoints, isn't it? For example, having Observable<Order> you can't fetch any HTTP related metadata. I think here we should fix it ASAP and that think about it.

In general, contents are application/json which is not "streamable" so I would say Single would be better than Flowable @cbornet

I would say Completable even is better than Single, there is no fun having "Void" returned, we just need a confirmation that such action is ok or failed.

@zkdzegede meanwhile the #7397 is under review, you can use fixed version with jitpack: https://jitpack.io/#wingsofovnia/swagger-codegen/642c0566de

It's the problem of all current RxJava2 endpoints, isn't it? For example, having Observable you can't fetch any HTTP related metadata. I think here we should fix it ASAP and that think about it.

Indeed, the correct return type should be Single<Response<Void>>

I would say Completable even is better than Single, there is no fun having "Void" returned, we just need a confirmation that such action is ok or failed.

With Single<Response<Void>> you have response headers, so that's better

@wing328 What version can I find this on?

@wingsofovnia Thank you for your help 馃挴

@zkdzegede the latest master has the fix. You can pull the build the JAR locally or use the SNAPSHOT version as mentioned in the README.

Was this page helpful?
0 / 5 - 0 ratings