Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recreating flask api call in Android with Retrofit

I have a flask app and api on a server that works with the following url sent from the terminal

curl -i -H "Content-type: application/json" -X GET http://myapp.com/890/14000/10000/007 -d '{"id":"3240f056c8f5fb"}'

I am trying to recreate this using retrofit on Android. I am using version 1.7 as this works with some legacy code not shown here. Here is the relevant part of the application class

DavesApi buildDavesApi() {
        Gson gson = new GsonBuilder()
                .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
                .create();

        return new RestAdapter.Builder()
                .setLogLevel(RestAdapter.LogLevel.FULL) // change this to FULL to see full JSON response
                .setEndpoint(DAVESENDPOINT)
                .setConverter(new GsonConverter(gson))
                .setRequestInterceptor(new RequestInterceptor() {
                    @Override
                    public void intercept(RequestFacade request) {
                        request.addHeader("Content-type", "application/json");
                    }
                })
                .build()
                .create(DavesApi.class);
    }

and the api class

public interface DavesApi {
    @Headers("\{\"id\"\:\"3240f056c8f5fb\"\}")
    @GET("/{importantnumber}/14000/10000/007")
    void getThumbnail(@Path("importantnumber") Integer id, Callback<DavesActivity> activity);
}

I am only getting generic errors at this point such as

 D/Retrofit: ---> HTTP GET http://myurl.com/420059/14000/10000/007
 D/Retrofit: '{"id": "3240f056c8f5fb"}'
 D/Retrofit: Content-Type: application/json
 D/Retrofit: ---> END HTTP (no body)
 D/Retrofit: <--- HTTP 400 http://myurl.com/420059/14000/10000/007 (2653ms)
 D/Retrofit: : HTTP/1.1 400 BAD REQUEST
 D/Retrofit: Connection: keep-alive
 D/Retrofit: Content-Length: 95
 D/Retrofit: Content-Type: application/json
 D/Retrofit: Date: Sun, 29 Nov 2015 23:08:45 GMT
 D/Retrofit: Server: ngx_openresty/1.4.3.6
 D/Retrofit: X-Android-Received-Millis: 1448838524561
 D/Retrofit: X-Android-Response-Source: NETWORK 400
 D/Retrofit: X-Android-Sent-Millis: 1448838523377
 D/Retrofit: {"description": "The browser (or proxy) sent a request that this server could not understand."}
 D/Retrofit: <--- END HTTP (95-byte body)
 E/activity_fragment: retrofit.RetrofitError: 400 BAD REQUEST

This is my first flask app and I am not entirely sure how to debug so any help here is also appreciated.

I also dont have access to server logs


Update

In order to try and track down the problem I edited the code on the server. If I simply return a string in the api then retrofit receives a response. If I try and return any data sent in the headers from retrofit I get an empty response whereas the curl request will get the appropriate response. I have tried this with response.data as well as response.json to ensure that its not just a json encoding issue. However, when doing this I need to remove the "Content-type", "application/json" header in order to not get the 400 posted earlier.

new log when returning response.data

 D/Retrofit: ---> HTTP GET http://myurl.com/420059/14000/10000/007
 D/Retrofit: test: header
 D/Retrofit: ---> END HTTP (no body)
 D/Retrofit: <--- HTTP 200 http://myurl.com/420059/14000/10000/007 (316ms)
 D/Retrofit: : HTTP/1.1 200 OK
 D/Retrofit: Connection: keep-alive
 D/Retrofit: Content-Length: 0
 D/Retrofit: Content-Type: text/html; charset=utf-8
 D/Retrofit: Date: Mon, 30 Nov 2015 20:34:54 GMT
 D/Retrofit: Server: ngx_openresty/1.4.3.6
 D/Retrofit: X-Android-Received-Millis: 1448915692589
 D/Retrofit: X-Android-Response-Source: NETWORK 200
 D/Retrofit: X-Android-Sent-Millis: 1448915692449
 D/Retrofit: X-Clacks-Overhead: GNU Terry Pratchett
 D/Retrofit: <--- END HTTP (0-byte body) // empty body :(
like image 635
EnduroDave Avatar asked Nov 27 '15 00:11

EnduroDave


1 Answers

Well it seems it took the addition of a bounty to force me to work this out :(

This is simply my missunderstanding of basic curl. Obviously the curl request was putting the data in the body whereas I took this for another header. Simply changing the code on server to look for request.header or changing the id to be in the @data part of a retrofit request worked.

can't believe I have wasted so much time and bounty on this blindly obvious error.

like image 78
EnduroDave Avatar answered Nov 14 '22 12:11

EnduroDave