Package Exports
- rn-grpc-bridge
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (rn-grpc-bridge) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
React Native gRPC Swift/Java bridge generator
If you are developing React Native app and using gRPC for backend communication when you need to bind native gRPC Swift/Android packages and communicate between native and javascript. React Native accepts only Dictionaries and Arrays with primitive types.
Features
- Generate Swift Unary calls code for JS mappings
- Generate iOS Swift bridge header
- Generate Typescript interfaces for JS/TS
- Generate Swift Streaming calls code for JS mappings
- Generate Android Unary code for JS mappings
- Generate Android Streaming code for JS mappings
Example Use case
- Lets say we have proto
message Book {
int64 isbn = 1;
string title = 2;
string author = 3;
int32 pages = 4;
bool isActivate = 5;
BookDetails details = 6;
}
message GetTypesRequest {
double dbl = 1;
float flt = 2;
int32 intr32 = 3;
int64 intr64 = 4;
uint32 uintr32 = 5;
uint64 uintr64 = 6;
sint32 suint32 = 7;
sint64 suint64 = 8;
fixed32 fxd32 = 9;
fixed64 fxd64 = 10;
sfixed32 sfxd32 = 11;
sfixed64 sfxd64 = 12;
bool bln = 13;
string str = 14;
bytes bytx = 15;
repeated Book books = 16;
Book book = 17;
}
message GetTypesResponse {
double dbl = 1;
float flt = 2;
int32 intr32 = 3;
int64 intr64 = 4;
uint32 uintr32 = 5;
uint64 uintr64 = 6;
sint32 suint32 = 7;
sint64 suint64 = 8;
fixed32 fxd32 = 9;
fixed64 fxd64 = 10;
sfixed32 sfxd32 = 11;
sfixed64 sfxd64 = 12;
bool bln = 13;
string str = 14;
bytes bytx = 15;
repeated Book books = 16;
Book book = 17;
}
service BookService {
rpc GetTypes (GetTypesRequest) returns (GetTypesResponse) {}
}
- Now if you want to call GetTypes method from javascript you need to write all these mappings
@objc(BookService)
class BookService: NSObject, GrpcService {
@objc func GetTypes(_ req$: [String: Any], resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {
let svc = BookServiceClient()
var req = Book_GetTypesRequest()
// request mapping
req.dbl = req$["dbl"] as? Double ?? 0
req.flt = req$["flt"] as? Float ?? 0
req.intr32 = Int32(req$["intr32"] as? Int ?? 0)
req.intr64 = Int64(req$["intr64"] as? Int ?? 0)
req.uintr32 = UInt32(req$["uintr32"] as? Int ?? 0)
req.uintr64 = UInt64(req$["uintr64"] as? Int ?? 0)
req.suint32 = Int32(req$["suint32"] as? Int ?? 0)
req.suint64 = Int64(req$["suint64"] as? Int ?? 0)
req.fxd32 = UInt32(req$["fxd32"] as? Int ?? 0)
req.fxd64 = UInt64(req$["fxd64"] as? Int ?? 0)
req.sfxd32 = Int32(req$["sfxd32"] as? Int ?? 0)
req.sfxd64 = Int64(req$["sfxd64"] as? Int ?? 0)
req.bln = req$["bln"] as? Bool ?? false
req.str = req$["str"] as? String ?? ""
req.bytx = req$["bytx"] as? Data ?? Data()
if let arr = req$["books"] as? [[String: Any]] {
for item in arr {
if let books_Book$ = item as? [String: Any] {
var books_Book = Book()
books_Book.isbn = Int64(books_Book$["isbn"] as? Int ?? 0)
books_Book.title = books_Book$["title"] as? String ?? ""
books_Book.author = books_Book$["author"] as? String ?? ""
books_Book.pages = Int32(books_Book$["pages"] as? Int ?? 0)
books_Book.isActivate = books_Book$["isActivate"] as? Bool ?? false
if let details_BookDetails$ = books_Book$["details"] as? [String: Any] {
var details_BookDetails = BookDetails()
details_BookDetails.pages = Int32(details_BookDetails$["pages"] as? Int ?? 0)
books_Book.details = details_BookDetails
}
req.books.append(books_Book)
}
}
}
if let book_Book$ = item["book"] as? [String: Any] {
var book_Book = Book()
book_Book.isbn = Int64(book_Book$["isbn"] as? Int ?? 0)
book_Book.title = book_Book$["title"] as? String ?? ""
book_Book.author = book_Book$["author"] as? String ?? ""
book_Book.pages = Int32(book_Book$["pages"] as? Int ?? 0)
book_Book.isActivate = book_Book$["isActivate"] as? Bool ?? false
if let details_BookDetails$ = book_Book$["details"] as? [String: Any] {
var details_BookDetails = BookDetails()
details_BookDetails.pages = Int32(details_BookDetails$["pages"] as? Int ?? 0)
book_Book.details = details_BookDetails
}
req.book = book_Book
}
// end request mapping
do {
let res = try svc.GetTypes(req)
var res$: [String: Any] = [:]
// response mapping
res$["dbl"] = res.dbl
res$["flt"] = res.flt
res$["intr32"] = res.intr32
res$["intr64"] = res.intr64
res$["uintr32"] = res.uintr32
res$["uintr64"] = res.uintr64
res$["suint32"] = res.suint32
res$["suint64"] = res.suint64
res$["fxd32"] = res.fxd32
res$["fxd64"] = res.fxd64
res$["sfxd32"] = res.sfxd32
res$["sfxd64"] = res.sfxd64
res$["bln"] = res.bln
res$["str"] = res.str
res$["bytx"] = res.bytx
var books$: [[String: Any]] = []
for item in res.books {
var _books_Book = item
var _books_Book$: [String: Any] = [:]
_books_Book$["isbn"] = _books_Book.isbn
_books_Book$["title"] = _books_Book.title
_books_Book$["author"] = _books_Book.author
_books_Book$["pages"] = _books_Book.pages
_books_Book$["isActivate"] = _books_Book.isActivate
var _details_BookDetails = _books_Book.details
var _details_BookDetails$: [String: Any] = [:]
_details_BookDetails$["pages"] = _details_BookDetails.pages
_books_Book$["details"] = _details_BookDetails$
books$.append(_books_Book$)
}
res$["books"] = books$
var _book_Book = res.book
var _book_Book$: [String: Any] = [:]
_book_Book$["isbn"] = _book_Book.isbn
_book_Book$["title"] = _book_Book.title
_book_Book$["author"] = _book_Book.author
_book_Book$["pages"] = _book_Book.pages
_book_Book$["isActivate"] = _book_Book.isActivate
var _details_BookDetails = _book_Book.details
var _details_BookDetails$: [String: Any] = [:]
_details_BookDetails$["pages"] = _details_BookDetails.pages
_book_Book$["details"] = _details_BookDetails$
res$["book"] = _book_Book$
// end response mapping
resolve(res$)
} catch {
reject("ERROR", error.localizedDescription, error)
}
}
}
- rn-grpc-bridge generator can do it for you
Usage
- Install
yarn add rn-grpc-bridge --dev
- Compile using protoc compiler
protoc \
--rn_out=${OUTDIR} \
--plugin=protoc-gen-rn=./node_modules/.bin/rn-grpc-bridge \
-I ./proto \
proto/*.proto
- Initialize services from react native. See generate grpc_config.swift for call arguments.
import { NativeModules, DebugService } from 'react-native';
import { DebugService, PingRequest } from './pb/debug_grpc_pb_types';
// inside some initial component
class InitialScreen {
async componentDidMount() {
const grpcConfig = NativeModules.GrpcConfig;
// init for local dev
await grpcConfig.initServices('localhost:9000', false, '');
// or for secure with TLS cert to staging/prod
// await grpcConfig.initServices('corp.staging.com', true, 'certname');
// it is also possible to set global for all services metadata
await grpcConfig.setMetadata({
'x-key': 'x-value',
'api-key': 'abc1'
});
// now we are ready to call grpc
const debugService: DebugService = NativeModules.DebugService;
const req: PingRequest = {
message: `ping from react native ${new Date().getTime()}`
};
const rsp = await debugService.ping(req);
console.log(rsp);
}
}
Docker
See example which uses Docker image to run rn-grpc-bridge without any external library.