Protobuf & TypeScript
Protobuf is the recommended format for applications. Compact binary messages reduce data transfer, and generated encoders and decoders process them efficiently. Generate the client once during development, then use typed requests and responses in your app.
1. Download the schemas
Section titled “1. Download the schemas”Save these four files together in your project’s proto/ directory:
2. Generate the client and TypeScript types
Section titled “2. Generate the client and TypeScript types”Install the runtime and development tools:
npm install protobufjsnpm install --save-dev protobufjs-cli typescriptmkdir -p src/generatedRun these commands from your project directory:
npx pbjs -t static-module -w es6 -o src/generated/planner.js proto/PlanRequest.proto proto/PlanResult.proto proto/Modes.proto proto/DirectionType.protonpx pbts -o src/generated/planner.d.ts src/generated/planner.jsYou now have:
| File | Purpose |
|---|---|
src/generated/planner.js | Encodes requests and decodes responses |
src/generated/planner.d.ts | TypeScript types and editor autocomplete |
This setup suits a browser application using a bundler such as Vite. Include both generated files in your project. The app uses the generated JavaScript at runtime; the .proto files are inputs to the generation step.
Regenerate both files when you update the schemas. You can add the two commands to a generate:proto script in your package.json.
3. Create a typed request
Section titled “3. Create a typed request”import { planner } from "./generated/planner";
const input: planner.IPlanRequest = { fromPlace: "52.0894,5.1102", toPlace: "52.0925,5.1813", timestamp: new Date().toISOString(), timeSlack: 0, userPreferences: { walkingSpeed: planner.UserSpeed.AVERAGE, bikingSpeed: planner.UserSpeed.AVERAGE, },};const request = planner.PlanRequest.create(input);const bytes = planner.PlanRequest.encode(request).finish();Use generated enum constants for modes, speeds and travel class. For example, planner.model.enumerations.TransitMode.RAIL selects the rail enum value.
4. Send and decode binary messages
Section titled “4. Send and decode binary messages”Connect to the public Infoplaza endpoint with your api_key. Protobuf is the default; mode=proto is optional. See API-key setup. Set binaryType so the browser delivers binary frames as an ArrayBuffer.
const endpoint = new URL("wss://api.infoplaza.com/v1/transit/implanner");endpoint.searchParams.set("api_key", INFOPLAZA_API_KEY); // From your app configurationconst socket = new WebSocket(endpoint);socket.binaryType = "arraybuffer";socket.addEventListener("open", () => socket.send(new Uint8Array(bytes).buffer),);
socket.addEventListener("message", (event) => { if (typeof event.data === "string") { const message = JSON.parse(event.data); if (message.type === "error") { console.error(message.payload.message); } return; }
const result = planner.model.PlanResult.decode(new Uint8Array(event.data)); for (const trip of result.trips) { console.log(trip.duration, trip.legs); }});Each binary frame contains one PlanResult. Keep listening for more journeys until the search completes. See the complete first request and connection lifecycle.
Working with JSON recipes
Section titled “Working with JSON recipes”The recipe pages use readable enum names. Convert a recipe’s payload to a Protobuf message with fromObject:
const request = planner.PlanRequest.fromObject(recipe.payload);const bytes = planner.PlanRequest.encode(request).finish();To turn a decoded result into a plain object with named enums:
const object = planner.model.PlanResult.toObject(result, { enums: String, longs: String, defaults: false,});For a JSON connection, send { type: 'planTrip', payload: input } as text and parse each response with JSON.parse. Both connections use text JSON envelopes for server errors.
The generation commands use the official protobufjs CLI. A downloadable Node.js client is also available.