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 project(':network-plugin')
|
||||||
implementation deps.protobuf
|
implementation deps.protobuf
|
||||||
implementation "com.squareup.retrofit2:retrofit:2.9.0"
|
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
|
compileOnly deps.jsr305
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,24 +9,23 @@ package com.facebook.flipper.plugins.retrofit2protobuf
|
|||||||
|
|
||||||
import com.facebook.flipper.android.AndroidFlipperClient
|
import com.facebook.flipper.android.AndroidFlipperClient
|
||||||
import com.facebook.flipper.core.FlipperArray
|
import com.facebook.flipper.core.FlipperArray
|
||||||
import com.facebook.flipper.core.FlipperObject
|
|
||||||
import com.facebook.flipper.core.FlipperValue
|
import com.facebook.flipper.core.FlipperValue
|
||||||
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin
|
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin
|
||||||
import com.facebook.flipper.plugins.retrofit2protobuf.adapter.GenericCallDefinitionsToMessageDefinitionsIfProtobuf
|
import com.facebook.flipper.plugins.retrofit2protobuf.adapter.GenericCallDefinitionsToMessageDefinitionsIfProtobuf
|
||||||
import com.facebook.flipper.plugins.retrofit2protobuf.adapter.RetrofitServiceToGenericCallDefinitions
|
import com.facebook.flipper.plugins.retrofit2protobuf.adapter.RetrofitServiceToGenericCallDefinitions
|
||||||
import com.facebook.flipper.plugins.retrofit2protobuf.model.CallNestedMessagesPayload
|
import com.facebook.flipper.plugins.retrofit2protobuf.model.CallNestedMessagesPayload
|
||||||
import me.haroldmartin.protobufjavatoprotobufjs.adapter.FullNamedMessagesToNestedMessages
|
|
||||||
|
|
||||||
object SendProtobufToFlipperFromRetrofit {
|
object SendProtobufToFlipperFromRetrofit {
|
||||||
operator fun invoke(baseUrl: String, service: Class<*>) {
|
operator fun invoke(baseUrl: String, service: Class<*>) {
|
||||||
AndroidFlipperClient.getInstanceIfInitialized()?.let { client ->
|
getNetworkPlugin()?.addProtobufDefinitions(
|
||||||
(client.getPlugin(NetworkFlipperPlugin.ID) as? NetworkFlipperPlugin)
|
baseUrl,
|
||||||
?.send(
|
generateProtobufDefinitions(service).toFlipperArray()
|
||||||
"addProtobufDefinitions",
|
)
|
||||||
FlipperObject.Builder().put(
|
}
|
||||||
baseUrl, generateProtobufDefinitions(service).toFlipperArray()
|
|
||||||
).build()
|
private fun getNetworkPlugin(): NetworkFlipperPlugin? {
|
||||||
)
|
return AndroidFlipperClient.getInstanceIfInitialized()?.let { client ->
|
||||||
|
client.getPlugin(NetworkFlipperPlugin.ID) as? NetworkFlipperPlugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,9 +38,9 @@ object SendProtobufToFlipperFromRetrofit {
|
|||||||
path = it.path,
|
path = it.path,
|
||||||
method = it.method,
|
method = it.method,
|
||||||
requestMessageFullName = it.requestMessageFullName,
|
requestMessageFullName = it.requestMessageFullName,
|
||||||
requestDefinitions = FullNamedMessagesToNestedMessages(it.requestModel),
|
requestDefinitions = it.requestModel,
|
||||||
responseMessageFullName = it.responseMessageFullName,
|
responseMessageFullName = it.responseMessageFullName,
|
||||||
responseDefinitions = FullNamedMessagesToNestedMessages(it.responseModel)
|
responseDefinitions = it.responseModel
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ internal object GenericCallDefinitionsToMessageDefinitionsIfProtobuf {
|
|||||||
path = definition.path,
|
path = definition.path,
|
||||||
method = definition.method,
|
method = definition.method,
|
||||||
responseMessageFullName = responseRootAndMessages?.rootFullName,
|
responseMessageFullName = responseRootAndMessages?.rootFullName,
|
||||||
responseModel = responseRootAndMessages?.messages,
|
responseModel = responseRootAndMessages?.descriptors,
|
||||||
requestMessageFullName = requestRootAndMessages?.rootFullName,
|
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<*>?
|
private val Method.requestBodyType: Class<*>?
|
||||||
get() {
|
get() {
|
||||||
parameterAnnotations.forEachIndexed { index, parameters ->
|
parameterAnnotations.forEachIndexed { index, annotations ->
|
||||||
parameters.forEach { annotation ->
|
annotations.forEach { annotation ->
|
||||||
if (annotation.annotationClass == retrofit2.http.Body::class) {
|
if (annotation.annotationClass == retrofit2.http.Body::class) {
|
||||||
return parameterTypes[index]
|
return parameterTypes[index]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
package com.facebook.flipper.plugins.retrofit2protobuf.model
|
package com.facebook.flipper.plugins.retrofit2protobuf.model
|
||||||
|
|
||||||
|
import com.facebook.flipper.core.FlipperArray
|
||||||
import com.facebook.flipper.core.FlipperObject
|
import com.facebook.flipper.core.FlipperObject
|
||||||
import com.facebook.flipper.core.FlipperValue
|
import com.facebook.flipper.core.FlipperValue
|
||||||
|
|
||||||
@@ -14,29 +15,34 @@ internal data class CallNestedMessagesPayload(
|
|||||||
val path: String,
|
val path: String,
|
||||||
val method: String,
|
val method: String,
|
||||||
val requestMessageFullName: String?,
|
val requestMessageFullName: String?,
|
||||||
val requestDefinitions: Map<String, Any>,
|
val requestDefinitions: Map<String, Any>?,
|
||||||
val responseMessageFullName: String?,
|
val responseMessageFullName: String?,
|
||||||
val responseDefinitions: Map<String, Any>
|
val responseDefinitions: Map<String, Any>?
|
||||||
) : FlipperValue {
|
) : FlipperValue {
|
||||||
override fun toFlipperObject(): FlipperObject {
|
override fun toFlipperObject(): FlipperObject {
|
||||||
return FlipperObject.Builder()
|
return FlipperObject.Builder()
|
||||||
.put("path", path)
|
.put("path", path)
|
||||||
.put("method", method)
|
.put("method", method)
|
||||||
.put("requestMessageFullName", requestMessageFullName)
|
.put("requestMessageFullName", requestMessageFullName)
|
||||||
.put("requestDefinitions", requestDefinitions.toFlipperObject())
|
.put("requestDefinitions", requestDefinitions?.toFlipperObject())
|
||||||
.put("responseMessageFullName", responseMessageFullName)
|
.put("responseMessageFullName", responseMessageFullName)
|
||||||
.put("responseDefinitions", responseDefinitions.toFlipperObject())
|
.put("responseDefinitions", responseDefinitions?.toFlipperObject())
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Map<*, *>.toFlipperObject(): FlipperObject {
|
private fun Map<*, *>.toFlipperObject(): FlipperObject {
|
||||||
val builder = FlipperObject.Builder()
|
val builder = FlipperObject.Builder()
|
||||||
this.forEach {
|
this.forEach { (key, value) ->
|
||||||
builder.put(
|
val castValue = when (value) {
|
||||||
it.key as String,
|
is Map<*, *> -> value.toFlipperObject()
|
||||||
if (it.value is Map<*, *>) (it.value as Map<*, *>).toFlipperObject() else it.value
|
is Iterable<*> -> value.toFlipperArray()
|
||||||
)
|
else -> value
|
||||||
|
}
|
||||||
|
builder.put(key as String, castValue)
|
||||||
}
|
}
|
||||||
return builder.build()
|
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
|
package com.facebook.flipper.plugins.retrofit2protobuf.model
|
||||||
|
|
||||||
import me.haroldmartin.protobufjavatoprotobufjs.model.FullNamedMessages
|
import me.haroldmartin.protobufjavatoprotobufjs.adapter.JsDescriptors
|
||||||
|
|
||||||
internal data class FullNamedMessagesCallDefinition(
|
internal data class FullNamedMessagesCallDefinition(
|
||||||
val path: String,
|
val path: String,
|
||||||
val method: String,
|
val method: String,
|
||||||
val requestMessageFullName: String?,
|
val requestMessageFullName: String?,
|
||||||
val responseMessageFullName: String?,
|
val responseMessageFullName: String?,
|
||||||
val responseModel: FullNamedMessages?,
|
val responseModel: JsDescriptors?,
|
||||||
val requestModel: FullNamedMessages?
|
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.
|
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
|
## iOS
|
||||||
|
|
||||||
To enable network inspection, add the following pod to your Podfile:
|
To enable network inspection, add the following pod to your Podfile:
|
||||||
|
|||||||
Reference in New Issue
Block a user