Ryan Cirese Ryan Cirese - 22 days ago 7
Android Question

curl to retrofit2 post command

I'm trying to get an access token from the gfycat api. Following their docs I'm able to get a good token in terminal with the following command.

curl -v -XPOST -d '{"client_id":"YOUR_ID_HERE", "client_secret": "YOUR_SECRET_HERE", "grant_type": "client_credentials"}' https://api.gfycat.com/v1/oauth/token


However when trying to to get the same results with my retrofit client the response body is null. Here's my code:

public class GfycatApiManager {
private static final String BASE_URL = "https://api.gfycat.com/v1/";
private static final String GRANT_TYPE = "client_credentials";
private static final String CLIENT_ID = "my id";
private static final String CLIENT_SECRET = "my secret";

private GfycatApiInterface api;

public GfycatApiManager() {
api = (new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build())
.create(GfycatApiInterface.class);
}

public void getToken(){
Call<AccessToken> call = api.getAccessToken(GRANT_TYPE, CLIENT_ID, CLIENT_SECRET);
call.enqueue(new Callback<AccessToken>() {
@Override
public void onResponse(Call<AccessToken> call, Response<AccessToken> response) {
//System.out.println(response.body().token_type);
//System.out.println(response.body().scope);
//System.out.println(response.body().expires_in);
//System.out.println(response.body().access_token);
}
@Override
public void onFailure(Call<AccessToken> call, Throwable t) {}
});

}
}


And the service...

public interface GfycatApiInterface {

@FormUrlEncoded
@POST("/oauth/token/")
Call<AccessToken> getAccessToken(@Field("grant_type") String grantType,
@Field("client_id") String clientId,
@Field("client_secret") String clientSecret);
}


And the token...

public class AccessToken {

@SerializedName("token_type")
@Expose
public String token_type;
@SerializedName("scope")
@Expose
public String scope;
@SerializedName("expires_in")
@Expose
public int expires_in;
@SerializedName("access_token")
@Expose
public String access_token;

}


Not sure if it's a problem in my post command or somewhere else but I can't figure it out. Please help :D

Answer

I was able to make the call using the @Body annotation. The following changes make it work for me :

GfycatApiInterface.java - remove the initial forward slash in the path and change the signature

public interface GfycatApiInterface {

    @POST("oauth/token/")
    Call<AccessToken> getAccessToken(@Body TokenRequest tokenRequest);
}

TokenRequest.java - New model class that holds the request parameters

public class TokenRequest {

    private String grant_type;
    private String client_id;
    private String client_secret;
    
    public TokenRequest(String grantType, String clientId, String clientSecret) {
        this.grant_type = grantType;
        this.client_id = clientId;
        this.client_secret = clientSecret;
    }
    
}

The getToken() call in GfycatApiManager.java should be using :

Call<AccessToken> call = api.getAccessToken(new TokenRequest(GRANT_TYPE, CLIENT_ID, CLIENT_SECRET));
Comments