jtti
January 22, 2025, 11:00am
1
Build and deploy gRPC server that echos both a fixed64
and int32
number
Add the gRPC service as gRPC resource
Build an app that posts a constant value and show the result from the service
Details: No code or error messages are shown. With grpcurl
I get the correct results:
$ grpcurl -plaintext -d '{"number": "17034143211355898120"}' retoolfixed64-nlb-7bc75fe38f59a2ab.elb.eu-west-1.amazonaws.com:50051 protos.HelloService/HelloFixed64
{
"number": "17034143211355898120"
}
You see the input equals the output.
Here you see the echo'ed result is wrong.
I'm a new user so I can't upload an attachment. The JSON of a clean and simple app is below.
JSON export
```json
{"uuid":"336c3388-d8ad-11ef-b7ce-c790ad5f2dec","page":{"id":366951618,"data":{"appState":"[\"~#iR\",[\"^ \",\"n\",\"appTemplate\",\"v\",[\"^ \",\"appMaxWidth\",\"100%\",\"appStyles\",\"\",\"appTesting\",null,\"appThemeId\",null,\"appThemeModeId\",null,\"appThemeName\",null,\"createdAt\",null,\"customComponentCollections\",[],\"customDocumentTitle\",\"\",\"customDocumentTitleEnabled\",false,\"customShortcuts\",[],\"experimentalDataTabEnabled\",true,\"experimentalFeatures\",[\"^ \",\"disableMultiplayerEditing\",false,\"multiplayerEditingEnabled\",false,\"sourceControlTemplateDehydration\",false],\"folders\",[\"~#iL\",[]],\"formAppSettings\",[\"^ \",\"customRedirectUrl\",\"\"],\"inAppRetoolPillAppearance\",\"NO_OVERRIDE\",\"instrumentationEnabled\",false,\"internationalizationSettings\",[\"^ \",\"internationalizationEnabled\",false,\"internationalizationFiles\",[]],\"isFetching\",false,\"isFormApp\",false,\"isGlobalWidget\",false,\"isMobileApp\",false,\"loadingIndicatorsDisabled\",false,\"markdownLinkBehavior\",\"auto\",\"mobileAppSettings\",[\"^ \",\"displaySetting\",[\"^ \",\"landscapeMode\",false,\"tabletMode\",false],\"mobileOfflineModeBannerMode\",\"default\",\"mobileOfflineModeDelaySync\",false,\"mobileOfflineModeEnabled\",false],\"mobileOfflineAssets\",[],\"multiScreenMobileApp\",false,\"notificationsSettings\",[\"^ \",\"globalQueryShowFailureToast\",true,\"globalQueryShowSuccessToast\",false,\"globalQueryToastDuration\",4.5,\"globalToastPosition\",\"bottomRight\"],\"pageCodeFolders\",[\"^ \"],\"pageLoadValueOverrides\",[\"^B\",[]],\"plugins\",[\"~#iOM\",[\"query1\",[\"^0\",[\"^ \",\"n\",\"pluginTemplate\",\"v\",[\"^ \",\"id\",\"query1\",\"uuid\",null,\"type\",\"datasource\",\"subtype\",\"GRPCQuery\",\"namespace\",null,\"resourceName\",\"18efe18b-45c0-416d-ada3-82e5e2ef8497\",\"resourceDisplayName\",\"Fixed64 test\",\"template\",[\"^15\",[\"queryRefreshTime\",\"\",\"serviceName\",\"protos.HelloService\",\"allowedGroupIds\",[\"^B\",[]],\"streamResponse\",false,\"lastReceivedFromResourceAt\",null,\"queryDisabledMessage\",\"\",\"servedFromCache\",false,\"offlineUserQueryInputs\",\"\",\"successMessage\",\"\",\"queryDisabled\",\"\",\"playgroundQuerySaveId\",\"latest\",\"workflowParams\",null,\"resourceNameOverride\",\"\",\"runWhenModelUpdates\",true,\"showFailureToaster\",true,\"query\",\"{\\n \\\"number\\\": {{ textInput1.value }}\\n}\",\"playgroundQueryUuid\",\"\",\"playgroundQueryId\",null,\"error\",null,\"workflowRunBodyType\",\"raw\",\"privateParams\",[\"^B\",[]],\"queryRunOnSelectorUpdate\",false,\"runWhenPageLoadsDelay\",\"\",\"data\",null,\"methodName\",\"HelloFixed64\",\"importedQueryInputs\",[\"^15\",[]],\"isImported\",false,\"showSuccessToaster\",true,\"cacheKeyTtl\",\"\",\"requestSentTimestamp\",null,\"metadata\",null,\"queryRunTime\",null,\"changesetObject\",\"\",\"offlineOptimisticResponse\",null,\"errorTransformer\",\"return data.error\",\"finished\",null,\"confirmationMessage\",null,\"isFetching\",false,\"changeset\",\"\",\"rawData\",null,\"queryTriggerDelay\",\"0\",\"resourceTypeOverride\",null,\"watchedParams\",[\"^B\",[]],\"enableErrorTransformer\",false,\"isHidden\",false,\"showLatestVersionUpdatedWarning\",false,\"timestamp\",0,\"importedQueryDefaults\",[\"^15\",[]],\"enableTransformer\",true,\"showUpdateSetValueDynamicallyToggle\",true,\"overrideOrgCacheForUserCache\",false,\"runWhenPageLoads\",false,\"transformer\",\"return data\",\"events\",null,\"queryTimeout\",\"10000\",\"workflowId\",null,\"requireConfirmation\",false,\"queryFailureConditions\",\"\",\"changesetIsObject\",false,\"enableCaching\",false,\"allowedGroups\",[\"^B\",[]],\"offlineQueryType\",\"None\",\"queryThrottleTime\",\"750\",\"updateSetValueDynamically\",false,\"notificationDuration\",\"\"]],\"style\",null,\"position2\",null,\"mobilePosition2\",null,\"mobileAppPosition\",null,\"tabIndex\",null,\"container\",\"\",\"^7\",\"~m1737542453353\",\"updatedAt\",\"~m1737542914639\",\"folder\",\"\",\"screen\",null]]],\"$main\",[\"^0\",[\"^ \",\"n\",\"pluginTemplate\",\"v\",[\"^ \",\"id\",\"$main\",\"^16\",null,\"^17\",\"frame\",\"^18\",\"Frame\",\"^19\",null,\"^1:\",null,\"^1;\",null,\"^1<\",[\"^15\",[\"type\",\"main\",\"sticky\",null,\"padding\",\"8px 12px\",\"enableFullBleed\",false,\"isHiddenOnDesktop\",false,\"isHiddenOnMobile\",false]],\"^1=\",[\"^15\",[]],\"^1>\",null,\"^1?\",null,\"^1@\",null,\"^1A\",null,\"^1B\",\"\",\"^7\",\"~m1737542857160\",\"^1C\",\"~m1737542857160\",\"^1D\",\"\",\"^1E\",null]]],\"textInput1\",[\"^0\",[\"^ \",\"n\",\"pluginTemplate\",\"v\",[\"^ \",\"id\",\"textInput1\",\"^16\",\"9025a951-c0ac-4fa5-903a-6dab15d0783f\",\"^17\",\"widget\",\"^18\",\"TextInputWidget2\",\"^19\",null,\"^1:\",null,\"^1;\",null,\"^1<\",[\"^15\",[\"spellCheck\",false,\"readOnly\",false,\"iconAfter\",\"\",\"showCharacterCount\",false,\"autoComplete\",false,\"enforceMaxLength\",false,\"maxLength\",null,\"hidden\",false,\"customValidation\",\"\",\"patternType\",\"\",\"hideValidationMessage\",false,\"textBefore\",\"\",\"validationMessage\",\"\",\"margin\",\"4px 8px\",\"textAfter\",\"\",\"showInEditor\",false,\"showClear\",false,\"pattern\",\"\",\"tooltipText\",\"\",\"labelAlign\",\"left\",\"formDataKey\",\"{{ self.id }}\",\"value\",\"16034143211355898120\",\"labelCaption\",\"\",\"labelWidth\",\"33\",\"autoFill\",\"\",\"placeholder\",\"Enter value\",\"label\",\"Input\",\"_validate\",false,\"labelWidthUnit\",\"%\",\"invalid\",false,\"iconBefore\",\"\",\"minLength\",null,\"inputTooltip\",\"\",\"events\",[\"^15\",[]],\"autoCapitalize\",\"none\",\"loading\",false,\"disabled\",false,\"labelPosition\",\"top\",\"labelWrap\",false,\"maintainSpaceWhenHidden\",false,\"required\",false]],\"^1=\",[\"^15\",[]],\"^1>\",[\"^0\",[\"^ \",\"n\",\"position2\",\"v\",[\"^ \",\"^17\",\"grid\",\"^1B\",\"\",\"rowGroup\",\"body\",\"subcontainer\",\"\",\"row\",0,\"col\",0,\"height\",0.2,\"width\",4,\"tabNum\",0,\"stackPosition\",null]]],\"^1?\",null,\"^1@\",null,\"^1A\",null,\"^1B\",\"\",\"^7\",\"~m1737542871137\",\"^1C\",\"~m1737542997509\",\"^1D\",\"\",\"^1E\",null]]],\"text1\",[\"^0\",[\"^ \",\"n\",\"pluginTemplate\",\"v\",[\"^ \",\"id\",\"text1\",\"^16\",\"7e9d1163-3a95-4658-8b4f-ab45f8345941\",\"^17\",\"widget\",\"^18\",\"TextWidget2\",\"^19\",null,\"^1:\",null,\"^1;\",null,\"^1<\",[\"^15\",[\"heightType\",\"auto\",\"horizontalAlign\",\"left\",\"hidden\",false,\"imageWidth\",\"fit\",\"margin\",\"4px 8px\",\"showInEditor\",false,\"verticalAlign\",\"center\",\"tooltipText\",\"\",\"value\",\"Echo: {{ query1.data?.number }}\",\"disableMarkdown\",false,\"overflowType\",\"scroll\",\"maintainSpaceWhenHidden\",false]],\"^1=\",[\"^15\",[]],\"^1>\",[\"^0\",[\"^ \",\"n\",\"position2\",\"v\",[\"^ \",\"^17\",\"grid\",\"^1B\",\"\",\"^1F\",\"body\",\"^1G\",\"\",\"row\",1.8,\"col\",0,\"^1H\",1,\"^1I\",3,\"^1J\",0,\"^1K\",null]]],\"^1?\",null,\"^1@\",null,\"^1A\",null,\"^1B\",\"\",\"^7\",\"~m1737542922957\",\"^1C\",\"~m1737542989807\",\"^1D\",\"\",\"^1E\",null]]]]],\"preloadedAppJavaScript\",null,\"preloadedAppJSLinks\",[],\"queryStatusVisibility\",false,\"responsiveLayoutDisabled\",false,\"rootScreen\",null,\"savePlatform\",\"web\",\"shortlink\",null,\"testEntities\",[],\"tests\",[],\"urlFragmentDefinitions\",[\"^B\",[]],\"version\",\"3.139.0\"]]]"},"changesRecord":[{"type":"WIDGET_TEMPLATE_UPDATE","payload":{"plugin":{"id":"textInput1","type":"widget","uuid":"9025a951-c0ac-4fa5-903a-6dab15d0783f","style":{},"folder":"","subtype":"TextInputWidget2","template":{"label":"Label","value":"16034143211355898120","events":{},"hidden":false,"margin":"4px 8px","invalid":false,"loading":false,"pattern":"","autoFill":"","disabled":false,"readOnly":false,"required":false,"_validate":false,"iconAfter":"","labelWrap":false,"maxLength":null,"minLength":null,"showClear":false,"textAfter":"","iconBefore":"","labelAlign":"left","labelWidth":"33","spellCheck":false,"textBefore":"","formDataKey":"{{ self.id }}","patternType":"","placeholder":"Enter value","tooltipText":"","autoComplete":false,"inputTooltip":"","labelCaption":"","showInEditor":false,"labelPosition":"top","autoCapitalize":"none","labelWidthUnit":"%","customValidation":"","enforceMaxLength":false,"validationMessage":"","showCharacterCount":false,"hideValidationMessage":false,"maintainSpaceWhenHidden":false},"container":"","createdAt":"2025-01-22T10:47:51.137Z","position2":{"col":0,"row":0,"type":"grid","width":4,"height":0.2,"tabNum":0,"rowGroup":"body","container":"","subcontainer":"","stackPosition":null},"updatedAt":"2025-01-22T10:47:57.627Z"},"update":{"label":"Input"},"widgetId":"textInput1","shouldRecalculateTemplate":true},"isUserTriggered":true}],"changesRecordV2":[{"data":{"op":"update","ids":["textInput1"],"tag":"plugin"},"type":"diff","version":1}],"gitSha":null,"checksum":null,"createdAt":"2025-01-22T10:49:59.760Z","updatedAt":"2025-01-22T10:49:59.760Z","pageId":3846188,"userId":61790},"modules":{}}
```
jtti
January 30, 2025, 12:07pm
3
I managed to work-around this issue by using gRPC gateway which exposes the gRPC service as HTTP.
Tess
January 30, 2025, 8:10pm
4
Thanks for sharing your workaround, @jtti
We have a bug report on file where some users have experienced gRPC resources in Retool converting strings to integers, I wonder if that is the issue I can reach out if our team ships a fix for that bug!
jtti
January 31, 2025, 1:06pm
5
Yeah it might be related; 64-bit integers (fixed64
, uint64
, int64
) must be encoded as JSON strings because of constraints in JavaScript. It looks like something is off when Retool converts that to the protobuf wire format.
1 Like