Hello i am trying to invoke a web service (using Retrofit) made by myself, with Slim4, however it is giving me the same error. I already went back and forth and tried many solutions i found on other threads however none of it worked yet .
This is my endpoint to do a get with Slim 4 and NOTORM library
$app->get('/api/anuncios', function ($request, $response) {
require_once('db/dbconnection.php');
foreach($db->anuncios()
as $row){
$data[] = $row;
}
echo json_encode($data, JSON_UNESCAPED_UNICODE);
return $response;
});
These are my Endpoints on Android Studio (i am only trying, for now, the first one)
interface EndPoints {
#GET("/RoomForStudents/api/anuncios/")
fun getAnuncios(): Call<List<Anuncio>>
/** #GET("/api/anuncios/{id}")
fun getAnunciosById(#Path("id") id: Int): Call<Anuncio>*/
}
My ServiceBuilder (i already added the gson, to solve another error , about JSON malforming)
object ServiceBuilder {
private val gson = GsonBuilder().setLenient().create()
private val client = OkHttpClient.Builder().build()
private val retrofit = Retrofit.Builder()
/**.baseUrl("https://tneveda.000webhostapp.com/")*/
.baseUrl("https://tneveda.000webhostapp.com/")
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client)
.build()
fun<T> buildService(service: Class<T>): T {
return retrofit.create(service)
}
}
I think the problem is somehow with the format of the Data that is readed in my webService, because i made a test with this Dummy Data https://jsonplaceholder.typicode.com/users and it worked, however with the data of my WebService it doesn't work, however i am having troubling in finding a solution
Thank you
Just to add the result of the get endpoint of my webservice
https://tneveda.000webhostapp.com/RoomForStudents/api/anuncios
EDIT
Noticed on postman, that after using my endpoints, i was getting the responde in html, and added this is the PHP file with the endpoints with SLIM/NOTORM
'''
header("Content-Type: application/json; charset=UTF-8");
'''
Also changed JSON_UNESCAPED_UNICODE to JSON_PRETTY_PRINT
and now my response in the server is in JSON format and pretty
However it is still giving me the same error
You should remove the last forward slash / from your #GET annotation.
#GET("/RoomForStudents/api/anuncios")
fun getAnuncios(): Call<List<Anuncio>>
As the last / is leading to a different endpoint, and your server is throwing a HttpNotFoundException.
So I'm trying to use an API from a website but inorder to use it i'll have to send my login informaton. The documentation shows me a python example on how to login.
R = requests.post('http://nova.astrometry.net/api/login', data={'request-json':
json.dumps({"apikey": "XXXXXXXX"})})
print(R.text)
So what is the Kotlin equivalent of the above code ? In the websites documentation it states
"Note the request-json=VALUE: we’re not sending raw JSON, we’re sending the JSON-encoded string as though it were a text field called request-json."
I have attempted to use Android Volley but im not entirely sure how to use it.
private fun plateSolve(){
val json=JSONObject(map).toString()
Log.d(TAG,"URL:$url")
Log.d(TAG,"Hashmap:$json")
JSONObject(map).toString()
val jsonObjectRequest = JsonObjectRequest(
Request.Method.POST, url, null,
{ response ->
try {
Log.d(TAG,"POST Response: %s".format(response.toString()))
}catch (e:Exception){
Log.d(TAG,"Exception: $e")
}
},
{ error ->
// TODO: Handle error
Log.d(TAG,"There Was an Error")
error.stackTraceToString()
}
)
// Access the RequestQueue through your singleton class.
VolleySingleton.instance?.addToRequestQueue(jsonObjectRequest)
}
Thanks in advance
it's not recommended to use volley anymore for android please use retrofit as its google's recommended library,the answer for your question is too big so i will write some checkpoints to do and also i have shared a simple working example with retrofit one of my own projects on github , hopefully this helps you
retrofit link - https://square.github.io/retrofit/
Insert library files in gradle
create response classes
create retrofit api class
4.create interface class with api calls
Github project with app using retrofit for api calls
https://github.com/zaidzak9/NewsApp
I set up a connection between Android and AWS Lambda which has the endpoint set to SageMaker. I am using the REST API during the connection, the AWS Cognito plug is set to be accessed without authorization.
I make a connection as described here:
https://aws.amazon.com/blogs/machine-learning/call-an-amazon-sagemaker-model-endpoint-using-amazon-api-gateway-and-aws-lambda/
My question is how to send this data:
{"data":"13.49,22.3,86.91,561.0,0.08752,0.07697999999999999,0.047510000000000004,0.033839999999999995,0.1809,0.057179999999999995,0.2338,1.3530000000000002,1.735,20.2,0.004455,0.013819999999999999,0.02095,0.01184,0.01641,0.001956,15.15,31.82,99.0,698.8,0.1162,0.1711,0.2282,0.1282,0.2871,0.06917000000000001"}
And how to view the received response later. Anyone know how to do it or where I can find tips on how to do it?
If I understand correctly, this is your system flow:
POST some data from your Android device
It gets received by API Gateway
And continues through to AWS Lambda
In AWS Lambda the data is extracted, and passed to Sage Maker
Creating a POST using AWS Amplify
To POST data form the Android device, follow the Amplify API (REST) category documentation.
Specifically, you can do something like:
val options = RestOptions.builder()
.addPath("/prod/predictbreastcancer")
.addBody("{\"data\":\"13.49,22.3,86.91,561.0,0.08752,0.07697999999999999,0.047510000000000004,0.033839999999999995,0.1809,0.057179999999999995,0.2338,1.3530000000000002,1.735,20.2,0.004455,0.013819999999999999,0.02095,0.01184,0.01641,0.001956,15.15,31.82,99.0,698.8,0.1162,0.1711,0.2282,0.1282,0.2871,0.06917000000000001\"}".toByteArray())
.build()
Amplify.API.post(options,
{ Log.i("Demo", "POST response = $it") },
{ Log.e("Demo", "POST failed", it) }
)
Creating POST body from EditText content
You mentioned you're using an EditText widget to gather the input data. I assume a user can enter a comma-separated list of values like 0.44, 6.11, etc.
To extract it's content and build the POST body, you can do:
val input = findViewById(R.id.input) as EditText
val body = JSONObject()
.put("data", input.text)
.toString()
.replaceAll("\"", "\\\"")
Displaying response in another Activity
Skimming the blog you referenced, I can't see an example of the response body content. But, here's how you can retrieve response JSON and pass it to a new activity.
Amplify.API.post(options,
{ response ->
val intent = Intent(this, YourOtherActivity::class.java)
intent.putExtra("json", response.data.asString())
runOnUiThread { startActivity(intent) }
},
{ /* handle error ... */ }
)
In YourOtherActivity, access the extra data in onCreate() like so:
val json = intent.getStringExtra("json")
I recently started update to okhttp3 to 4.x
In doing so I am getting following build time error:
Using 'url(): HttpUrl' is an error. moved to val
The issue is happening when I am trying to get url from request object obtained via call:
e.g
call.enque(callback : Callback){
override fun onFailure(call : Call, t:Throwable) {
val url = call.request().url().toString
}
}
I looked up further and the Url object within Request is val aka final now.
Also, no directions on their upgrade guide https://square.github.io/okhttp/upgrading_to_okhttp_4/
I would appreciate for any suggestions on another way to obtain Url.
Using 'url(): HttpUrl' is an error. moved to val
This means you should change the function call url() to a property access url.
okhttp 4 comes with replaceWith param in the deprecation annotation that makes e.g. Android Studio to offer that fix automatically with right-click/alt-enter on the error:
#Deprecated(
message = "moved to val",
replaceWith = ReplaceWith(expression = "url"),
level = DeprecationLevel.ERROR)
From comments:
Upon further investigation I found out that the request() or Request object is from Retrofit 2. And Retrofit 2 returns call object from okhttp3
That's an issue with Android Studio. You can work around it with explicit cast to okhttp 4 types, e.g. (call.request() as Request).url.
In my case, I just had to remove the brackets:
call.request().url() -> call.request().url
I have a Retrofit call where I want to handle HTTP and Retrofit errors when calling an API.
So when a failure happens, I need to cache the request into a RoomDB/SQLite for when the API comes back online, or connection improves there is a routine that sends all those requests to the API.
x.enqueue(object : Callback<PayloadResponse> {
override fun onResponse(
call: Call<PayloadResponse>,
response: Response<PayloadResponse>
) {
...
val errorMessage = when {
response.code() != HttpURLConnection.HTTP_OK -> {
// Need the original Payload here so I can insert that data into RoomDB/SQLite
"An error occured duing API Call (NOT OK) &{response.code()}"
}
...
Same situation I need for the onFailure() callback.
Can I access the original request in these contexts? If so how?
Once I have encountered the same problem. My approach was debugging first parameter of retrofit callback's onResponse and onFailure.
call: Call<PayloadResponse>
call.request()
It contains all kind of information about your call / request e.g url, parameters, method. However, retrieving request data is not straightforward, consistent, and prone to bugs.
Then, I started using Kotlin coroutine which gives async process with sync nature of coding.
interface RetrofitApi{
#GET("your-route")
suspend fun sampleApiMethod(request:SampleRequest):Response<SampleCustomObject>
}
Your retrofit api methods may look like above.
CoroutineScope(Dispatchers.Main).launch {
val request = SampleRequest()
val deferred = async { apiService.sampleApiMethod(request) }
val result = deferred.await()
if(result.code() == 200){
// Do something
}else{
// Cache SampleRequest()
}
}
You can modify as much as to make it look better and utilize optimized light weight threads. It is one of the ways for me to handle such situations. It's just a hint, you may modify to have structurally and architecturally correct design in your project.