Apigen
Generate standard Protobuf and ts-rest APIs following best-practice design patterns
Install / Use
/learn @slavovojacek/ApigenREADME
<h2 align="center">Generate standard Protobuf and ts-rest APIs following best-practice design patterns</h2> <p align="center"> Inspired by <a href="https://www.oreilly.com/library/view/api-design-patterns/9781617295850/" target="_blank">API Design Patterns</a> </p>
Install
Homebrew:
brew install thames-technology/tap/apigen
Go:
go install github.com/thames-technology/apigen
Getting started
Protobuf
Create BookService with author parent resource:
apigen proto -r book -p author -pkg bookservice.v1alpha1 -w
This will generate the following standard API definitions in proto/bookservice/v1alpha1/service.proto:
syntax = "proto3";
package bookservice.v1alpha1;
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";
// =============================================================================
// Service definition
// =============================================================================
// The BookService defines the standard methods for managing books.
service BookService {
// Creates a new book in the library.
rpc CreateBook(CreateBookRequest) returns (CreateBookResponse);
// Retrieves a book by its ID.
rpc GetBook(GetBookRequest) returns (GetBookResponse);
// Lists books with pagination support.
rpc ListBooks(ListBooksRequest) returns (ListBooksResponse);
// Updates an existing book.
rpc UpdateBook(UpdateBookRequest) returns (UpdateBookResponse);
// Deletes a book by its ID.
rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty);
}
// =============================================================================
// Service request and response messages
// =============================================================================
// Request message for CreateBook method.
message CreateBookRequest {
// UUID used to prevent duplicate requests.
optional string request_id = 1;
// The book to be created.
Book book = 2;
}
// Response message for CreateBook method.
message CreateBookResponse {
// The created book.
Book book = 1;
}
// Request message for GetBook method.
message GetBookRequest {
// ID of the book to retrieve.
string book_id = 1;
}
// Response message for GetBook method.
message GetBookResponse {
// The retrieved book.
Book book = 1;
}
// Request message for ListBooks method.
message ListBooksRequest {
// The maximum number of books to return.
optional int32 page_size = 1;
// The token to retrieve the next page of results.
optional string page_token = 2;
// ID of the author to list books for.
optional string author_id = 3;
}
// Response message for ListBooks method.
message ListBooksResponse {
// The list of books.
repeated Book results = 1;
// Token to retrieve the next page of results.
string next_page_token = 2;
// Estimated total number of results.
int32 total_results_estimate = 3;
}
// Request message for UpdateBook method.
message UpdateBookRequest {
// UUID used to prevent duplicate requests.
optional string request_id = 1;
// ID of the book to update.
string book_id = 2;
// The book to be updated.
Book book = 3;
// The field mask specifying the fields to update.
google.protobuf.FieldMask update_mask = 4;
}
// Response message for UpdateBook method.
message UpdateBookResponse {
// The updated book.
Book book = 1;
}
// Request message for DeleteBook method.
message DeleteBookRequest {
// ID of the book to delete.
string id = 1;
}
// =============================================================================
// Resource messages
// =============================================================================
// The Book message represents a book in the library.
message Book {
// Unique identifier for the book.
string id = 1;
// When the book was created.
google.protobuf.Timestamp create_time = 2;
// When the book was last updated.
google.protobuf.Timestamp update_time = 3;
// ID of the author of the book.
string author_id = 4;
// Additional fields for the book.
// TODO: Add fields here.
}
Create AuthorService definition without a parent resource:
apigen proto -r author -pkg authorservice.v1alpha1 -w
This will generate the following standard API definitions in proto/authorservice/v1alpha1/service.proto:
syntax = "proto3";
package authorservice.v1alpha1;
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";
// =============================================================================
// Service definition
// =============================================================================
// The AuthorService defines the standard methods for managing authors.
service AuthorService {
// Creates a new author in the library.
rpc CreateAuthor(CreateAuthorRequest) returns (CreateAuthorResponse);
// Retrieves a author by its ID.
rpc GetAuthor(GetAuthorRequest) returns (GetAuthorResponse);
// Lists authors with pagination support.
rpc ListAuthors(ListAuthorsRequest) returns (ListAuthorsResponse);
// Updates an existing author.
rpc UpdateAuthor(UpdateAuthorRequest) returns (UpdateAuthorResponse);
// Deletes a author by its ID.
rpc DeleteAuthor(DeleteAuthorRequest) returns (google.protobuf.Empty);
}
// =============================================================================
// Service request and response messages
// =============================================================================
// Request message for CreateAuthor method.
message CreateAuthorRequest {
// UUID used to prevent duplicate requests.
optional string request_id = 1;
// The author to be created.
Author author = 2;
}
// Response message for CreateAuthor method.
message CreateAuthorResponse {
// The created author.
Author author = 1;
}
// Request message for GetAuthor method.
message GetAuthorRequest {
// ID of the author to retrieve.
string author_id = 1;
}
// Response message for GetAuthor method.
message GetAuthorResponse {
// The retrieved author.
Author author = 1;
}
// Request message for ListAuthors method.
message ListAuthorsRequest {
// The maximum number of authors to return.
optional int32 page_size = 1;
// The token to retrieve the next page of results.
optional string page_token = 2;
}
// Response message for ListAuthors method.
message ListAuthorsResponse {
// The list of authors.
repeated Author results = 1;
// Token to retrieve the next page of results.
string next_page_token = 2;
// Estimated total number of results.
int32 total_results_estimate = 3;
}
// Request message for UpdateAuthor method.
message UpdateAuthorRequest {
// UUID used to prevent duplicate requests.
optional string request_id = 1;
// ID of the author to update.
string author_id = 2;
// The author to be updated.
Author author = 3;
// The field mask specifying the fields to update.
google.protobuf.FieldMask update_mask = 4;
}
// Response message for UpdateAuthor method.
message UpdateAuthorResponse {
// The updated author.
Author author = 1;
}
// Request message for DeleteAuthor method.
message DeleteAuthorRequest {
// ID of the author to delete.
string id = 1;
}
// =============================================================================
// Resource messages
// =============================================================================
// The Author message represents a author in the library.
message Author {
// Unique identifier for the author.
string id = 1;
// When the author was created.
google.protobuf.Timestamp create_time = 2;
// When the author was last updated.
google.protobuf.Timestamp update_time = 3;
// Additional fields for the author.
// TODO: Add fields here.
}
TypeScript with ts-rest
[!NOTE] Learn more about ts-rest: https://ts-rest.com/
Create book contract with author parent resource:
apigen ts-rest -r book -p author -w
This will generate the following standard API definitions in contracts/bookContract.ts:
import { initContract } from '@ts-rest/core';
import { z } from 'zod';
// ====================================================================================================================
// Schemas
// ====================================================================================================================
// Timestamps using ISO 8601 format
const Timestamp = z.string().datetime().describe('ISO 8601 format timestamp');
// Book schema
export const Book = z.object({
id: z.string().ulid().describe('Unique identifier for the book'),
createTime: Timestamp.describe('When the book was created'),
updateTime: Timestamp.describe('When the book was last updated'),
authorId: z.string().ulid().describe('ID of the author of the book'),
});
// ====================================================================================================================
// Request and response schemas
// ====================================================================================================================
export const CreateBookRequest = z.object({
requestId: z.string().uuid().optional().describe('UUID used to prevent duplicate requests'),
book: Book.omit({ id: true, createTime: true, updateTime: true }),
});
export const CreateBookResponse = z.object({
book: Book,
});
export const GetBookRequest = z.object({
bookId: z.string().ulid().describe('The unique identifier of the book'),
});
export const GetBookResponse = z.object({
book: Book,
});
export const ListBooksRequest = z.object({
pageSize: z.number().int().min(1).max(1000).default(100).
Related Skills
gh-issues
342.0kFetch GitHub issues, spawn sub-agents to implement fixes and open PRs, then monitor and address PR review comments. Usage: /gh-issues [owner/repo] [--label bug] [--limit 5] [--milestone v1.0] [--assignee @me] [--fork user/repo] [--watch] [--interval 5] [--reviews-only] [--cron] [--dry-run] [--model glm-5] [--notify-channel -1002381931352]
oracle
342.0kBest practices for using the oracle CLI (prompt + file bundling, engines, sessions, and file attachment patterns).
tmux
342.0kRemote-control tmux sessions for interactive CLIs by sending keystrokes and scraping pane output.
xurl
342.0kA CLI tool for making authenticated requests to the X (Twitter) API. Use this skill when you need to post tweets, reply, quote, search, read posts, manage followers, send DMs, upload media, or interact with any X API v2 endpoint.
