Update Protobuf support (#2381)
Summary: **Update protobuf library with new support for `enum` and `oneof` types** ## Changelog - Update plugin code for library API changes and other cleanup - Add instructions to readme Pull Request resolved: https://github.com/facebook/flipper/pull/2381 Test Plan: see demo app at https://github.com/hbmartin/protobuf_java_to_protobufjs Reviewed By: priteshrnandgaonkar Differential Revision: D28831035 Pulled By: passy fbshipit-source-id: 46e196293330b615394606bd3486ea47ad6a0630
This commit is contained in:
committed by
Facebook GitHub Bot
parent
b7d7326bae
commit
62967314c1
@@ -25,7 +25,7 @@ android {
|
||||
implementation project(':network-plugin')
|
||||
implementation deps.protobuf
|
||||
implementation "com.squareup.retrofit2:retrofit:2.9.0"
|
||||
implementation "com.github.hbmartin:protobuf_java_to_protobufjs:0.0.1"
|
||||
implementation "com.github.hbmartin:protobuf_java_to_protobufjs:0.1.0"
|
||||
compileOnly deps.jsr305
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,24 +9,23 @@ package com.facebook.flipper.plugins.retrofit2protobuf
|
||||
|
||||
import com.facebook.flipper.android.AndroidFlipperClient
|
||||
import com.facebook.flipper.core.FlipperArray
|
||||
import com.facebook.flipper.core.FlipperObject
|
||||
import com.facebook.flipper.core.FlipperValue
|
||||
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin
|
||||
import com.facebook.flipper.plugins.retrofit2protobuf.adapter.GenericCallDefinitionsToMessageDefinitionsIfProtobuf
|
||||
import com.facebook.flipper.plugins.retrofit2protobuf.adapter.RetrofitServiceToGenericCallDefinitions
|
||||
import com.facebook.flipper.plugins.retrofit2protobuf.model.CallNestedMessagesPayload
|
||||
import me.haroldmartin.protobufjavatoprotobufjs.adapter.FullNamedMessagesToNestedMessages
|
||||
|
||||
object SendProtobufToFlipperFromRetrofit {
|
||||
operator fun invoke(baseUrl: String, service: Class<*>) {
|
||||
AndroidFlipperClient.getInstanceIfInitialized()?.let { client ->
|
||||
(client.getPlugin(NetworkFlipperPlugin.ID) as? NetworkFlipperPlugin)
|
||||
?.send(
|
||||
"addProtobufDefinitions",
|
||||
FlipperObject.Builder().put(
|
||||
baseUrl, generateProtobufDefinitions(service).toFlipperArray()
|
||||
).build()
|
||||
)
|
||||
getNetworkPlugin()?.addProtobufDefinitions(
|
||||
baseUrl,
|
||||
generateProtobufDefinitions(service).toFlipperArray()
|
||||
)
|
||||
}
|
||||
|
||||
private fun getNetworkPlugin(): NetworkFlipperPlugin? {
|
||||
return AndroidFlipperClient.getInstanceIfInitialized()?.let { client ->
|
||||
client.getPlugin(NetworkFlipperPlugin.ID) as? NetworkFlipperPlugin
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,9 +38,9 @@ object SendProtobufToFlipperFromRetrofit {
|
||||
path = it.path,
|
||||
method = it.method,
|
||||
requestMessageFullName = it.requestMessageFullName,
|
||||
requestDefinitions = FullNamedMessagesToNestedMessages(it.requestModel),
|
||||
requestDefinitions = it.requestModel,
|
||||
responseMessageFullName = it.responseMessageFullName,
|
||||
responseDefinitions = FullNamedMessagesToNestedMessages(it.responseModel)
|
||||
responseDefinitions = it.responseModel
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@ internal object GenericCallDefinitionsToMessageDefinitionsIfProtobuf {
|
||||
path = definition.path,
|
||||
method = definition.method,
|
||||
responseMessageFullName = responseRootAndMessages?.rootFullName,
|
||||
responseModel = responseRootAndMessages?.messages,
|
||||
responseModel = responseRootAndMessages?.descriptors,
|
||||
requestMessageFullName = requestRootAndMessages?.rootFullName,
|
||||
requestModel = requestRootAndMessages?.messages
|
||||
requestModel = requestRootAndMessages?.descriptors
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,8 +53,8 @@ private val Array<Annotation>.urlPathAndMethod: Pair<String, String>?
|
||||
|
||||
private val Method.requestBodyType: Class<*>?
|
||||
get() {
|
||||
parameterAnnotations.forEachIndexed { index, parameters ->
|
||||
parameters.forEach { annotation ->
|
||||
parameterAnnotations.forEachIndexed { index, annotations ->
|
||||
annotations.forEach { annotation ->
|
||||
if (annotation.annotationClass == retrofit2.http.Body::class) {
|
||||
return parameterTypes[index]
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
package com.facebook.flipper.plugins.retrofit2protobuf.model
|
||||
|
||||
import com.facebook.flipper.core.FlipperArray
|
||||
import com.facebook.flipper.core.FlipperObject
|
||||
import com.facebook.flipper.core.FlipperValue
|
||||
|
||||
@@ -14,29 +15,34 @@ internal data class CallNestedMessagesPayload(
|
||||
val path: String,
|
||||
val method: String,
|
||||
val requestMessageFullName: String?,
|
||||
val requestDefinitions: Map<String, Any>,
|
||||
val requestDefinitions: Map<String, Any>?,
|
||||
val responseMessageFullName: String?,
|
||||
val responseDefinitions: Map<String, Any>
|
||||
val responseDefinitions: Map<String, Any>?
|
||||
) : FlipperValue {
|
||||
override fun toFlipperObject(): FlipperObject {
|
||||
return FlipperObject.Builder()
|
||||
.put("path", path)
|
||||
.put("method", method)
|
||||
.put("requestMessageFullName", requestMessageFullName)
|
||||
.put("requestDefinitions", requestDefinitions.toFlipperObject())
|
||||
.put("requestDefinitions", requestDefinitions?.toFlipperObject())
|
||||
.put("responseMessageFullName", responseMessageFullName)
|
||||
.put("responseDefinitions", responseDefinitions.toFlipperObject())
|
||||
.put("responseDefinitions", responseDefinitions?.toFlipperObject())
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
private fun Map<*, *>.toFlipperObject(): FlipperObject {
|
||||
val builder = FlipperObject.Builder()
|
||||
this.forEach {
|
||||
builder.put(
|
||||
it.key as String,
|
||||
if (it.value is Map<*, *>) (it.value as Map<*, *>).toFlipperObject() else it.value
|
||||
)
|
||||
this.forEach { (key, value) ->
|
||||
val castValue = when (value) {
|
||||
is Map<*, *> -> value.toFlipperObject()
|
||||
is Iterable<*> -> value.toFlipperArray()
|
||||
else -> value
|
||||
}
|
||||
builder.put(key as String, castValue)
|
||||
}
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
private fun Iterable<*>.toFlipperArray(): FlipperArray =
|
||||
fold(FlipperArray.Builder()) { builder, value -> builder.put(value as? String) }.build()
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
|
||||
package com.facebook.flipper.plugins.retrofit2protobuf.model
|
||||
|
||||
import me.haroldmartin.protobufjavatoprotobufjs.model.FullNamedMessages
|
||||
import me.haroldmartin.protobufjavatoprotobufjs.adapter.JsDescriptors
|
||||
|
||||
internal data class FullNamedMessagesCallDefinition(
|
||||
val path: String,
|
||||
val method: String,
|
||||
val requestMessageFullName: String?,
|
||||
val responseMessageFullName: String?,
|
||||
val responseModel: FullNamedMessages?,
|
||||
val requestModel: FullNamedMessages?
|
||||
val responseModel: JsDescriptors?,
|
||||
val requestModel: JsDescriptors?
|
||||
)
|
||||
|
||||
@@ -49,6 +49,25 @@ new OkHttpClient.Builder()
|
||||
|
||||
As interceptors can modify the request and response, add the Flipper interceptor after all others to get an accurate view of the network traffic.
|
||||
|
||||
### Protobuf / Retrofit Integration
|
||||
|
||||
If you are using Retrofit with Protobuf request or response types, you can setup automatic decoding so that the network inspector can display a human readable payload. First you must add the separate dependency:
|
||||
|
||||
```groovy
|
||||
dependencies {
|
||||
debugImplementation 'com.facebook.flipper:flipper-retrofit2-protobuf-plugin:0.91.2'
|
||||
}
|
||||
```
|
||||
|
||||
Then call `SendProtobufToFlipperFromRetrofit` for each service class.
|
||||
|
||||
```kotlin
|
||||
import com.facebook.flipper.plugins.retrofit2protobuf.SendProtobufToFlipperFromRetrofit
|
||||
|
||||
SendProtobufToFlipperFromRetrofit("https://baseurl.com/", MyApiService::class.java)
|
||||
```
|
||||
|
||||
|
||||
## iOS
|
||||
|
||||
To enable network inspection, add the following pod to your Podfile:
|
||||
|
||||
Reference in New Issue
Block a user