{"id":38410048,"url":"https://github.com/soundphilosopher/basic-grpc-service-node","last_synced_at":"2026-01-17T04:02:58.166Z","repository":{"id":313176438,"uuid":"1035607406","full_name":"soundphilosopher/basic-grpc-service-node","owner":"soundphilosopher","description":"Basic gRPC service written in TypeScript","archived":false,"fork":false,"pushed_at":"2025-12-01T21:59:13.000Z","size":161,"stargazers_count":0,"open_issues_count":5,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-04T11:58:13.176Z","etag":null,"topics":["cloudevents","grpc","learning","protobuf","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/soundphilosopher.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-10T18:53:02.000Z","updated_at":"2025-09-10T12:09:05.000Z","dependencies_parsed_at":"2025-09-04T11:35:46.820Z","dependency_job_id":"cba479b7-ae53-4d61-9d31-f7dcba72d351","html_url":"https://github.com/soundphilosopher/basic-grpc-service-node","commit_stats":null,"previous_names":["soundphilosopher/basic-grpc-service-node"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/soundphilosopher/basic-grpc-service-node","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soundphilosopher%2Fbasic-grpc-service-node","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soundphilosopher%2Fbasic-grpc-service-node/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soundphilosopher%2Fbasic-grpc-service-node/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soundphilosopher%2Fbasic-grpc-service-node/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/soundphilosopher","download_url":"https://codeload.github.com/soundphilosopher/basic-grpc-service-node/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soundphilosopher%2Fbasic-grpc-service-node/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28494159,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T02:39:23.645Z","status":"ssl_error","status_checked_at":"2026-01-17T02:34:19.649Z","response_time":85,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloudevents","grpc","learning","protobuf","typescript"],"created_at":"2026-01-17T04:02:58.038Z","updated_at":"2026-01-17T04:02:58.149Z","avatar_url":"https://github.com/soundphilosopher.png","language":"TypeScript","readme":"# 🚀 Basic gRPC Service: The TypeScript Edition\n\n[![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge\u0026logo=typescript\u0026logoColor=white)](https://www.typescriptlang.org/)\n[![Node.js](https://img.shields.io/badge/Node.js-43853D?style=for-the-badge\u0026logo=node.js\u0026logoColor=white)](https://nodejs.org/)\n[![gRPC](https://img.shields.io/badge/gRPC-4285F4?style=for-the-badge\u0026logo=grpc\u0026logoColor=white)](https://grpc.io/)\n[![Fastify](https://img.shields.io/badge/Fastify-000000?style=for-the-badge\u0026logo=fastify\u0026logoColor=white)](https://www.fastify.io/)\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE)\n[![Buf](https://img.shields.io/badge/Buf-235BDB?style=flat\u0026logo=buf\u0026logoColor=white)](https://buf.build/)\n[![ConnectRPC](https://img.shields.io/badge/ConnectRPC-654FF0?style=flat\u0026logo=connect\u0026logoColor=white)](https://connectrpc.com/)\n[![HTTP/2](https://img.shields.io/badge/HTTP%2F2-Enabled-green?style=flat)](https://http2.github.io/)\n[![TLS](https://img.shields.io/badge/TLS-Secured-green?style=flat\u0026logo=letsencrypt\u0026logoColor=white)](https://en.wikipedia.org/wiki/Transport_Layer_Security)\n\n\u003e *\"Why write boring microservices when you can build something that actually talks back?\"*\n\nWelcome to the most entertaining basic gRPC service you'll ever encounter! This isn't just another \"Hello World\" - it's a fully-featured gRPC service that includes an ELIZA-style therapist, background processing simulation, and all the modern TypeScript/Node.js goodness you crave.\n\n## ✨ What Makes This Special?\n\n🎭 **Three Distinct Personalities in One Service:**\n- **Hello**: Your friendly neighborhood greeter with CloudEvent superpowers\n- **Talk**: A streaming ELIZA therapist bot (because who doesn't need therapy while debugging?)\n- **Background**: A process simulator that pretends to spin up services across different protocols\n\n🔒 **Security First**: Local TLS certificates with `mkcert` (because even localhost deserves encryption)\n\n⚡ **Modern Stack**: ConnectRPC + Fastify + TypeScript + Buf CLI (the cool kids' table)\n\n🌊 **Streaming Ready**: Both client and server streaming, because sometimes one message just isn't enough\n\n## 🛠️ Prerequisites\n\nBefore we dive into this TypeScript wonderland, make sure you have:\n\n- **Node.js** (because obviously)\n- **npm** (comes free with Node.js, like ketchup with fries)\n- **[Buf CLI](https://buf.build)** (the protobuf Swiss Army knife)\n- **mkcert** (for those sweet, sweet local certificates)\n- **grpcurl** *(optional, but highly recommended for showing off)*\n\n### Quick Setup for the Impatient\n\n```bash\n# Install buf (if you haven't already)\nnpm install -g @bufbuild/buf\n\n# Install mkcert (macOS)\nbrew install mkcert\n\n# Install mkcert (Linux)\ncurl -JLO \"https://dl.filippo.io/mkcert/latest?for=linux/amd64\"\nchmod +x mkcert-v*-linux-amd64\nsudo mv mkcert-v*-linux-amd64 /usr/local/bin/mkcert\n```\n\n## 🚀 Getting Started\n\n### 1. Clone \u0026 Install\n```bash\ngit clone \u003cyour-repo\u003e\ncd basic-grpc-service-node\nnpm install\n```\n\n### 2. Generate Your Certificates (Trust Issues Much?)\n```bash\nnpm run cert:generate\n```\n*This creates local certificates that your browser will actually trust. Magic!*\n\n### 3. Generate Proto Code (Optional, but Fun)\n```bash\nnpm run buf:generate\n```\n*Watch as Buf transforms your `.proto` files into beautiful TypeScript. It's like a protobuf makeover show!*\n\n### 4. Start the Show\n```bash\nnpm start\n```\n\n🎉 **Boom!** Your gRPC service is now running on `https://127.0.0.1:8443` with all the bells, whistles, and TLS goodness.\n\n## 🎪 Meet Your Service Methods\n\n### 👋 `Hello` - The Friendly Greeter\n**What it does:** Takes your message and wraps it in a CloudEvent like a present\n\n```bash\n# Using buf curl (the modern way)\nbuf curl --schema ./proto -d '{\"message\": \"Universe\"}' \\\n  https://127.0.0.1:8443/basic.v1.BasicService/Hello\n\n# Using grpcurl (the classic way)\ngrpcurl 127.0.0.1:8443 basic.v1.BasicService/Hello -d '{\"message\": \"Universe\"}'\n```\n\n**Response:** A CloudEvent containing a greeting that would make your grandmother proud.\n\n### 💬 `Talk` - Your Personal Streaming Therapist\n**What it does:** Engages you in meaningful conversation using ELIZA-style responses. It's like having a therapist, but one that runs on your localhost.\n\n```bash\n# Stream some deep thoughts\ncat \u003c\u003cEOM | grpcurl 127.0.0.1:8443 basic.v1.BasicService/Talk\n{\"message\": \"Hello doctor\"}\n{\"message\": \"I feel anxious about my code\"}\n{\"message\": \"Why do my tests always fail?\"}\n{\"message\": \"goodbye\"}\nEOM\n```\n\n**Pro tip:** The therapist recognizes \"bye\", \"exit\", \"goodbye\", and \"quit\" as session-ending cues. It's very respectful of boundaries.\n\n### ⚙️ `Background` - The Process Whisperer\n**What it does:** Simulates spinning up multiple background services across different protocols (REST, gRPC, GraphQL, WebSockets, you name it). Streams progress updates every 2 seconds.\n\n```bash\n# Start 5 imaginary services\nbuf curl --schema ./proto -d '{\"processes\": 5}' \\\n  https://127.0.0.1:8443/basic.v1.BasicService/Background\n```\n\n**What you'll see:** Real-time updates as \"services\" start up across random protocols. It's like `docker-compose up` but with more imagination and less disk space usage.\n\n## 🕵️ Service Discovery \u0026 Introspection\n\n### List All Services\n```bash\n# Modern way\nbuf curl --schema ./proto https://127.0.0.1:8443 --list-services\n\n# Classic way\ngrpcurl 127.0.0.1:8443 list\n```\n\n### Explore Methods\n```bash\n# See what BasicService can do\nbuf curl --schema ./proto https://127.0.0.1:8443/basic.v1.BasicService --list-methods\n\n# Or the grpcurl way\ngrpcurl 127.0.0.1:8443 list basic.v1.BasicService\n```\n\n## 🏗️ Architecture Highlights\n\n### The Stack\n- **Fastify**: Because Express is so 2019\n- **ConnectRPC**: gRPC for the web-first world\n- **TypeScript**: Because `any` is not a type (fight me)\n- **Buf**: Protobuf management that doesn't make you cry\n- **HTTP/2 + TLS**: Because we're not animals\n\n### The Magic Sauce\n- **CloudEvents**: Every response is wrapped in a CloudEvent because standards matter\n- **Graceful Shutdown**: SIGINT/SIGTERM handling that would make a Unix admin proud\n- **Health Checks**: Built-in health endpoint (because monitoring is love)\n- **Reflection API**: Your gRPC client can discover services dynamically\n- **Structured Logging**: Pino-powered logs that actually help debug\n\n## 🎯 What's Next?\n\n- [ ] **Unit Tests** (because future you will thank present you)\n- [ ] **Integration Tests** (trust, but verify)\n- [ ] **Docker Support** (containerize all the things!)\n- [ ] **Kubernetes Manifests** (because why not?)\n- [ ] **More Streaming Methods** (the streams must flow)\n- [ ] **Authentication** (not all requests are created equal)\n\n## 🤔 Why This Exists\n\nThis service started as a simple \"Hello World\" gRPC example but evolved into something more interesting. It demonstrates:\n\n- Modern TypeScript gRPC development with ConnectRPC\n- Proper TLS setup for local development\n- Streaming patterns (both client and server-side)\n- CloudEvents integration\n- Service reflection and health checks\n- Graceful shutdown patterns\n\nPlus, who doesn't need a therapist that speaks Protocol Buffers?\n\n## 🎭 Fun Facts\n\n- The `Talk` service implements ELIZA, one of the first chatbot programs from the 1960s\n- Background processes are randomly assigned protocols from a list of 10 different types\n- Every response includes CloudEvents metadata because we believe in standards\n- The service supports both HTTP/1.1 and HTTP/2 because we're inclusive like that\n\n---\n\n*Built with ❤️, ☕, and a healthy dose of TypeScript strictness*\n\n**Questions? Issues? Existential Crises?** Open an issue and let's talk! (Or use the Talk method - it's a good listener.)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoundphilosopher%2Fbasic-grpc-service-node","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsoundphilosopher%2Fbasic-grpc-service-node","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoundphilosopher%2Fbasic-grpc-service-node/lists"}