DEV Community

Cover image for Document RAG and GraphRAG APIs with HazelJS
Muhammad Arslan
Muhammad Arslan

Posted on

Document RAG and GraphRAG APIs with HazelJS

Real-world document ingestion, semantic search, RAG Q&A, and knowledge-graph retrieval—all in one production-ready REST API


Introduction

Retrieval-augmented generation (RAG) has become the standard way to ground LLMs in your own data. But production RAG is more than “chunk and embed”: you need flexible ingestion (files, web, GitHub, YouTube), semantic search, and—for complex, multi-hop questions—knowledge-graph–backed retrieval (GraphRAG).

The HazelJS RAG Documents Starter demonstrates exactly that. Built on HazelJS and @hazeljs/rag, it ships with every document loader in the package, a full ingest API, semantic vector search, RAG Q&A, and a complete GraphRAG pipeline (entity extraction, community detection, local/global/hybrid search). In this post we walk through what’s in the starter and how to use it.


What’s in the box

Feature Component Source type
Local text TextFileLoader .txt
Markdown (heading splits) MarkdownFileLoader .md, .mdx
JSON JSONFileLoader .json
CSV CSVFileLoader .csv
HTML HtmlFileLoader .html, .htm
Recursive directory DirectoryLoader any supported type
Web scraping WebLoader any URL
YouTube transcripts YouTubeTranscriptLoader YouTube URLs
GitHub repos GitHubLoader GitHub REST API
Word / PDF DocxLoader, PdfLoader .docx, .pdf (optional deps)
Semantic search MemoryVectorStore + OpenAIEmbeddings
RAG Q&A RAGPipeline + GPT
GraphRAG GraphRAGPipeline, CommunityDetector, CommunitySummarizer any Document[]
GraphRAG search Local (BFS) + global (community reports) + hybrid entity & thematic queries

You get a single REST API: ingest from files or URLs, search by meaning, ask questions with citations, and run GraphRAG build + local/global/hybrid search—all with health checks and production-style structure.


Quick start

cd hazeljs-rag-documents-starter
npm install
cp .env.example .env   # add OPENAI_API_KEY
npm run dev
Enter fullscreen mode Exit fullscreen mode

Server runs at http://localhost:3000. Ingest the bundled sample docs:

curl -X POST http://localhost:3000/api/ingest/directory \
  -H "Content-Type: application/json" \
  -d '{"dirPath":"./sample-docs","recursive":true,"tags":["sample"]}'
Enter fullscreen mode Exit fullscreen mode

Then try semantic search or RAG Q&A (see examples below).


Ingest API: one interface, many loaders

The starter exposes one family of endpoints for all supported sources:

Endpoint Loader Typical body
POST /api/ingest/file Auto by extension { filePath, tags? }
POST /api/ingest/directory DirectoryLoader { dirPath, recursive?, include?, exclude?, tags? }
POST /api/ingest/url WebLoader { url, selector?, label?, tags? }
POST /api/ingest/urls WebLoader (batch) { urls[], selector?, tags? }
POST /api/ingest/youtube YouTubeTranscriptLoader { videoUrl, segmentDuration?, tags? }
POST /api/ingest/github GitHubLoader { owner, repo, ref?, directory?, extensions?, maxFiles?, tags? }
POST /api/ingest/text Inline { content, title?, metadata? }

Every ingest response includes documentsLoaded, chunksIndexed, loader name, and optional ids. Optional peer deps: pdf-parse, mammoth, cheerio for PDF, Word, and selector-based HTML.


Knowledge API: search and RAG Q&A

After ingestion, the Knowledge API gives you vector search and RAG:

Endpoint Description Body
POST /api/knowledge/search Semantic similarity search { q, topK?, minScore?, filter? }
POST /api/knowledge/ask RAG Q&A (retrieve + GPT, with sources) { question, topK?, minScore?, filter?, systemPrompt? }
GET /api/knowledge/stats Document counts and sources
DELETE /api/knowledge/clear Wipe the knowledge base

Example: semantic search

curl -X POST http://localhost:3000/api/knowledge/search \
  -H "Content-Type: application/json" \
  -d '{"q":"How does dependency injection work in HazelJS?","topK":4,"minScore":0.35}'
Enter fullscreen mode Exit fullscreen mode

Example: RAG Q&A

curl -X POST http://localhost:3000/api/knowledge/ask \
  -H "Content-Type: application/json" \
  -d '{"question":"What vector stores does @hazeljs/rag support and how do I swap them?","topK":5}'
Enter fullscreen mode Exit fullscreen mode

Responses include answer, sources, and duration. Out of the box the starter uses MemoryVectorStore; for production you can swap in Qdrant or Pinecone in the RAG pipeline service without changing the rest of the app.


GraphRAG: knowledge graph + community reports

GraphRAG goes beyond flat vector similarity. It:

  1. Extracts entities and relationships from documents using the LLM (CONCEPT, TECHNOLOGY, PERSON, USES, DEPENDS_ON, etc.).
  2. Builds a knowledge graph (nodes = entities, edges = typed relationships).
  3. Detects communities with the Label Propagation Algorithm (no extra config).
  4. Generates community reports — LLM-written summaries per cluster.
  5. Retrieves in three modes: local (entity-centric BFS), global (community reports), and hybrid (both merged, recommended default).
Mode How it works Best for
local Seed entities → K-hop traversal → entity + relationship context “What is X?”, “How does Y relate to Z?”
global Rank community reports by query relevance → thematic summaries “What are the main themes?”
hybrid Run local + global in parallel, merge context, one synthesis call General default

Build the graph from the sample docs:

curl -X POST http://localhost:3000/api/graphrag/build \
  -H "Content-Type: application/json" \
  -d '{"dirPath":"./sample-docs"}'
Enter fullscreen mode Exit fullscreen mode

Hybrid search (default):

curl -X POST http://localhost:3000/api/graphrag/search \
  -H "Content-Type: application/json" \
  -d '{"query":"How does HazelJS dependency injection work with modules?"}'
Enter fullscreen mode Exit fullscreen mode

Local (entity-centric) and global (thematic):

curl -X POST http://localhost:3000/api/graphrag/search/local \
  -H "Content-Type: application/json" \
  -d '{"query":"AgentGraph and SupervisorAgent","depth":3}'

curl -X POST http://localhost:3000/api/graphrag/search/global \
  -H "Content-Type: application/json" \
  -d '{"query":"What are the main architectural layers of HazelJS?"}'
Enter fullscreen mode Exit fullscreen mode

You can also inspect the graph and communities:

  • GET /api/graphrag/graph — full graph (entities, edges, communities)
  • GET /api/graphrag/communities — community reports only
  • GET /api/graphrag/stats — entity/relationship/community counts

Project structure

hazeljs-rag-documents-starter/
├── src/
│   ├── main.ts
│   ├── app.module.ts
│   ├── rag/           # RAGPipeline, embeddings, vector store
│   ├── ingest/        # All loaders, DTOs, POST /api/ingest/*
│   ├── knowledge/     # Search, ask, stats, clear
│   ├── graphrag/      # Build, search (local/global/hybrid), graph/communities/stats
│   └── health/        # GET /health, /health/ready
├── sample-docs/       # TXT, MD, CSV, JSON, HTML to try immediately
├── .env.example
└── README.md
Enter fullscreen mode Exit fullscreen mode

Health: GET /health (liveness), GET /health/ready (readiness, e.g. API key check).


Environment and production notes

Key env vars: OPENAI_API_KEY (required), EMBEDDING_MODEL, QA_MODEL, CHUNK_SIZE, CHUNK_OVERLAP, SEARCH_TOP_K, SEARCH_MIN_SCORE. GraphRAG: GRAPH_EXTRACTION_CHUNK_SIZE, GRAPH_COMMUNITY_REPORTS, GRAPH_MAX_COMMUNITY_SIZE, GRAPH_LOCAL_DEPTH, GRAPH_LOCAL_TOPK, GRAPH_GLOBAL_TOPK. See the starter README for the full list.

For production, replace MemoryVectorStore in the RAG pipeline service with QdrantStore or PineconeStore; the ingest and knowledge controllers stay unchanged.


Summary

The HazelJS RAG Documents Starter gives you:

  • Unified ingest — files, directories, URLs, YouTube, GitHub, and raw text via a single REST surface.
  • Semantic search and RAG Q&A — vector store + GPT with configurable chunking and models.
  • GraphRAG — entity/relationship extraction, community detection, and local/global/hybrid search for richer answers.

Clone it, set OPENAI_API_KEY, and you have a production-style document RAG + GraphRAG API in minutes. For more on HazelJS and @hazeljs/rag, see hazeljs.com and the HazelJS repository.

Top comments (0)