Skip to content

Conversation

jdaily
Copy link

@jdaily jdaily commented Jun 23, 2025

Add OpenAPI Tags Support to Encore Client Generation

Overview

This PR implements support for OpenAPI tags in Encore's API directives, allowing developers to organize their endpoints in the generated OpenAPI specification with custom tags using Encore's existing tag infrastructure.

Motivation

Currently, Encore generates OpenAPI specifications without custom organization tags, making it difficult for developers to group related endpoints in documentation and client generation tools. OpenAPI tags are a standard way to organize endpoints into logical groups (e.g., "Users", "Management", "Admin").

This feature addresses the need for better endpoint organization in generated OpenAPI specs while maintaining backward compatibility with existing API directives and leveraging Encore's proven tag system.

Changes

Core Implementation

1. Enhanced API Endpoint Structure

File: v2/parser/apis/api/api.go

  • Added OpenAPITags []string field to Endpoint struct
  • Updated tag validation to extract OpenAPI tags from tag:openapi-* directives
  • Added logic to separate OpenAPI tags from middleware tags
  • OpenAPI tags are extracted by removing the openapi- prefix from tag names

2. Error Handling

File: v2/parser/apis/api/errors.go

  • Added errInvalidOpenAPITag error for invalid OpenAPI tag validation

3. Protocol Buffer Schema

File: proto/encore/parser/meta/v1/meta.proto

  • Added repeated string openapi_tags = 20; to RPC message
  • Regenerated .pb.go files with proper field support

4. OpenAPI Generation

File: pkg/clientgen/openapi/openapi.go

  • Updated to utilize rpc.GetOpenapiTags() in spec generation
  • OpenAPI tags are properly included in generated operations

5. Metadata Conversion

File: v2/app/legacymeta/legacymeta.go

  • Added mapping from ep.OpenAPITags to rpc.OpenapiTags during conversion

Testing

API Parser Tests

File: v2/parser/apis/api/api_test.go

  • Test single OpenAPI tag parsing with tag:openapi-Users
  • Test multiple OpenAPI tags parsing with multiple tag:openapi-* directives
  • Test coexistence with middleware tags (e.g., tag:openapi-Users tag:middleware-auth)
  • Test validation of invalid empty tags (tag:openapi-)

OpenAPI Generation Tests

File: pkg/clientgen/openapi/openapi_test.go

  • Test OpenAPI spec generation with tags
  • Test endpoints without tags
  • Test empty tag arrays
  • Verify correct tag inclusion in generated JSON

Implementation Approach

This implementation leverages Encore's existing tag system rather than creating new directive fields. This approach provides several benefits:

  1. Consistency: Uses the existing, well-tested tag infrastructure
  2. No Breaking Changes: Doesn't require new directive parsing logic
  3. Namespace Separation: openapi- prefix clearly separates from middleware tags
  4. Multiple Tags: Can mix OpenAPI and middleware tags seamlessly
  5. Validation: Uses existing tag validation patterns

Usage

Developers can now use OpenAPI tags in their API directives using the existing tag system with an openapi- namespace:

// Single OpenAPI tag
//encore:api public method=GET path=/users tag:openapi-users
func GetUsers(ctx context.Context) (*UserList, error) {
    // Implementation
}

// Multiple OpenAPI tags
//encore:api public method=POST path=/users tag:openapi-users tag:openapi-management
func CreateUser(ctx context.Context, req *CreateUserRequest) (*User, error) {
    // Implementation
}

// Mix with middleware tags
//encore:api public method=DELETE path=/users/:id tag:openapi-users tag:middleware-auth
func DeleteUser(ctx context.Context, id string) error {
    // Implementation
}

Generated OpenAPI Impact

The above examples generate OpenAPI specification with proper tags:

paths:
  /users:
    get:
      tags:
        - users
      # ... rest of endpoint spec
    post:
      tags:
        - users
        - management
      # ... rest of endpoint spec
  /users/{id}:
    delete:
      tags:
        - users
      # ... rest of endpoint spec (middleware-auth doesn't appear in OpenAPI)

Backward Compatibility

This implementation is fully backward compatible:

  • Existing middleware tags continue to work unchanged
  • Existing APIs without OpenAPI tags continue to work
  • New OpenAPI tags are completely optional
  • No changes required to existing codebases

Testing

All tests pass:

  • Unit tests for API parsing and validation
  • Integration tests for OpenAPI generation
  • Backward compatibility verified

Related

  • Addresses the need for better endpoint organization in generated OpenAPI specs
  • Maintains backward compatibility with existing API directives
  • Follows existing Encore directive patterns and validation
  • Separates OpenAPI tags from existing middleware tag functionality

Note: This implementation uses Encore's existing tag infrastructure with an openapi- namespace prefix, ensuring clean separation from middleware functionality while maintaining consistency with established patterns.

- Add OpenAPITags field to Endpoint struct
- Extract OpenAPI tags from 'tag:openapi-*' directives
- Update protobuf schema with openapi_tags field
- Add OpenAPI tags to generated OpenAPI specifications
- Include comprehensive unit tests for both API parsing and OpenAPI generation
- Maintain backward compatibility with existing middleware tags

Usage:
//encore:api public tag:openapi-Users tag:openapi-management
//encore:api private tag:openapi-Admin tag:middleware-auth

removing gen
Copy link

encore-cla bot commented Jun 23, 2025

All committers have signed the CLA.

@eandre
Copy link
Member

eandre commented Jun 30, 2025

Please use the same protoc versions that we use, in order to minimize the diff etc

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