Skip to content

@W-19991461 Enhance AmfHelperMixin and Namespace with gRPC support #77#79

Merged
alexpmule merged 2 commits intomasterfrom
grpc-adoption-2
Nov 28, 2025
Merged

@W-19991461 Enhance AmfHelperMixin and Namespace with gRPC support #77#79
alexpmule merged 2 commits intomasterfrom
grpc-adoption-2

Conversation

@alexpmule
Copy link
Contributor

@alexpmule alexpmule commented Nov 28, 2025

gRPC Support Implementation in AMF Helper Mixin

Quick summary

  • Added new helper methods for gRPC API support in AmfHelperMixin, including methods to check if an API is gRPC, retrieve service and method names, and compute stream types.
  • Introduced new gRPC API definitions in JSON format and updated the .gitignore to include new API files.
  • Updated TypeScript definitions to include new gRPC methods and properties.
  • Modified deployment workflow to switch Node.js version to 18 for improved compatibility.

🎯 Overview

This PR implements comprehensive gRPC support in the amf-helper-mixin by adding 20+ new helper methods that enable API Console components to work seamlessly with gRPC APIs. The implementation provides detection, parsing, and utility methods for gRPC services, methods, stream types, and message schemas.

🔧 Changes Made

1. Core gRPC Helper Methods

API Detection & Validation

_isGrpcApi(api)           // Detects if API contains gRPC operations
_isGrpcOperation(operation) // Validates if operation is gRPC
_isGrpcService(endpoint)   // Checks if endpoint is gRPC service
_isGrpcMessageType(shape)  // Validates gRPC message types

Service & Method Extraction

_computeGrpcServices(webApi)        // Gets all gRPC services
_computeGrpcServiceName(endpoint)   // Extracts service name
_computeGrpcMethods(service)        // Gets methods for a service
_computeGrpcMethodName(operation)   // Extracts method name
_computeGrpcMethodSignature(op, svc) // Builds "Service.Method" signature

Stream Type Handling

_getGrpcStreamType(operation)           // Returns: unary, client_streaming, etc.
_getGrpcStreamTypeDisplayName(type)     // Returns: "Client Streaming"
_getGrpcStreamTypeBadge(type)          // Returns: "C" (for UI badges)

Schema & Message Processing

_computeGrpcRequestSchema(operation)   // Gets request message schema
_computeGrpcResponseSchema(operation)  // Gets response message schema
_computeGrpcMessageTypes(api)         // Gets all message types for Types section
_computeGrpcPackageName(api)          // Extracts gRPC package name

2. Namespace Extension

Added grpcStreamType property to the core vocabulary namespace:

// src/Namespace.js
ns.aml.vocabularies.core.grpcStreamType = `${coreKey}grpcStreamType`;

3. AmfLoader Helper Methods

Enhanced AmfLoader with gRPC-specific lookup methods:

AmfLoader.lookupGrpcService(model, serviceName)     // Find service by name
AmfLoader.lookupGrpcMethod(model, service, method)  // Find specific method

4. Test Infrastructure

  • 40+ comprehensive tests covering all methods and edge cases
  • Integration tests demonstrating real-world usage
  • Both compact and regular model support
  • Error handling and validation tests

🚀 Usage Examples

Basic gRPC Detection

class MyComponent extends AmfHelperMixin(LitElement) {
  
  checkApiType() {
    if (this._isGrpcApi(this.amf)) {
      console.log('This is a gRPC API!');
      const packageName = this._computeGrpcPackageName(this.amf);
      console.log('Package:', packageName); // "helloworld"
    }
  }
}

Navigation Component Integration

class ApiNavigationComponent extends AmfHelperMixin(LitElement) {
  
  computeNavigationItems() {
    const webApi = this._computeWebApi(this.amf);
    const items = [];
    
    // Add gRPC services
    const grpcServices = this._computeGrpcServices(webApi);
    if (grpcServices) {
      grpcServices.forEach(service => {
        const serviceName = this._computeGrpcServiceName(service);
        const methods = this._computeGrpcMethods(service);
        
        items.push({
          name: serviceName,
          type: 'grpc-service',
          children: methods.map(method => ({
            name: this._computeGrpcMethodName(method),
            streamType: this._getGrpcStreamType(method),
            badge: this._getGrpcStreamTypeBadge(this._getGrpcStreamType(method)),
            signature: this._computeGrpcMethodSignature(method, service)
          }))
        });
      });
    }
    
    return items;
  }
}

Method Documentation Component

class ApiMethodDocumentationComponent extends AmfHelperMixin(LitElement) {
  
  computeMethodData() {
    const method = this._computeMethodModel(this.webApi, this.selectedMethod);
    
    if (this._isGrpcOperation(method)) {
      return {
        type: 'grpc',
        streamType: this._getGrpcStreamType(method),
        streamTypeDisplay: this._getGrpcStreamTypeDisplayName(this._getGrpcStreamType(method)),
        requestSchema: this._computeGrpcRequestSchema(method),
        responseSchema: this._computeGrpcResponseSchema(method),
        // Hide REST-specific UI elements
        showUrlPanel: false,
        showSnippets: false
      };
    }
    
    return this.computeRestMethodData(method);
  }
}

Stream Type Display

// Stream type mapping for UI
const streamType = this._getGrpcStreamType(operation);
const badge = this._getGrpcStreamTypeBadge(streamType);
const displayName = this._getGrpcStreamTypeDisplayName(streamType);

console.log(streamType);    // "client_streaming"
console.log(badge);         // "C"
console.log(displayName);   // "Client Streaming"

// Render in template
html`
  <span class="method-badge stream-${streamType}">${badge}</span>
  <span class="stream-type">${displayName}</span>
`;

Using AmfLoader Helpers in Tests

// Find specific gRPC service and method
const service = AmfLoader.lookupGrpcService(grpcModel, 'Greeter');
const method = AmfLoader.lookupGrpcMethod(grpcModel, 'Greeter', 'SayHello');

if (method) {
  const streamType = this._getGrpcStreamType(method);
  const signature = this._computeGrpcMethodSignature(method, service);
  console.log(`${signature} is ${streamType}`); // "Greeter.SayHello is unary"
}

🏗️ Implementation Details

Stream Type Mapping

The implementation maps gRPC stream types to HTTP methods in AMF:

gRPC Stream Type HTTP Method Badge Display Name
unary POST U "Unary"
client_streaming PUBLISH C "Client Streaming"
server_streaming SUBSCRIBE S "Server Streaming"
bidi_streaming PUBSUB B "Bidirectional Streaming"

Media Type Detection

gRPC operations are identified by these media types:

  • application/grpc
  • application/grpc+proto

File Structure

Following repository patterns, gRPC test data uses standard naming:

  • apis/grpc-api.json (regular model)
  • apis/grpc-api-compact.json (compact model)

🧪 Testing Strategy

Comprehensive Test Coverage

  • Unit tests for each helper method
  • Integration tests for real-world scenarios
  • Edge case handling (undefined, null, empty data)
  • Both model formats (compact and regular)
  • AmfLoader helper tests for service/method lookup

Test Categories

  1. Detection Tests - API/operation/service validation
  2. Extraction Tests - Service/method name and data retrieval
  3. Stream Type Tests - Type detection and display formatting
  4. Schema Tests - Request/response schema extraction
  5. Integration Tests - Complete workflow scenarios
  6. Error Handling - Graceful handling of invalid data

🔄 Migration Path

For Existing Components

  1. Import the mixin (no changes needed if already using AmfHelperMixin)
  2. Add gRPC detection using _isGrpcApi() or _isGrpcOperation()
  3. Use appropriate helpers based on component needs
  4. Update templates to handle gRPC-specific data

Backward Compatibility

  • No breaking changes to existing API
  • All existing functionality preserved
  • New methods are additive only
  • Graceful degradation for non-gRPC APIs

📚 Documentation

  • GRPC_HELPERS.md - Complete method reference

Ready for integration into api-navigation, api-method-documentation, and other API Console components!

- Added new helper methods for gRPC API support in AmfHelperMixin, including methods to check if an API is gRPC, retrieve service and method names, and compute stream types.
- Introduced new gRPC API definitions in JSON format and updated the .gitignore to include new API files.
- Updated TypeScript definitions to include new gRPC methods and properties.
- Modified deployment workflow to switch Node.js version to 18 for improved compatibility.
@alexpmule alexpmule merged commit b72669d into master Nov 28, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants