GraphPress API

GraphPress API

A portfolio-grade mini blogging platform with a GraphQL + REST hybrid API. Node.js and Express serve queries, mutations, pagination, and nes...

JavaScript Git GraphQL Node.js Express MongoDB Bootstrap
Responsive Design Authentication File Upload GraphQL API Public Blog
★ 0.0 (0 ratings)

Share

Overview

GraphPress is a portfolio-grade blogging backend that demonstrates how to combine GraphQL for rich reads and writes with REST for binary uploads in a single Express application. Authors register, log in with JWT, draft and publish articles with slugs and cover images, manage categories and tags, receive nested comments with moderation, and track likes and bookmarks—all exposed through a typed GraphQL schema with pagination. A Bootstrap static frontend ships in the same repo for demos: home feed, article page, login, author dashboard, upload helper, GraphiQL, and a custom GraphQL playground.

The Challenge

Teams learning GraphQL often see toy schemas disconnected from real auth, file handling, and role-based access. Clients evaluating custom blog or CMS backends need a credible reference that shows hybrid API design—GraphQL for flexible data graphs, REST where multipart uploads are simpler—plus production patterns like JWT context, draft visibility rules, comment moderation, and seed data for instant portfolio demos without manual database setup.

Approach

Built a layered Node.js app: Mongoose models for users, articles, categories, tags, comments, likes, and bookmarks; SDL schema with enums for article and comment status; resolver modules split by domain; services for business logic; JWT middleware resolving the current user into GraphQL context. File uploads stay on REST routes with Multer and static serving under /uploads. A seed import script resets MongoDB and loads 30 users, 30 articles, 40 comments, likes, and bookmarks. The public Bootstrap UI calls the same API clients would use, proving end-to-end flows without a separate SPA build step.

Architecture

Entry in server.js: CORS, JSON body, static public/ and uploads/, graphqlHTTP at /graphql with graphiql and async context.user from resolveUser. Schema in graphql/schema.js; resolvers in graphql/resolvers/ (user, article, comment). Models use mongoose-paginate-v2 for list endpoints. Upload routes in routes/upload.js with auth middleware. Utils cover JWT signing, bcrypt passwords, slugify, and role checks. Seed JSON lives under database/seed/; scripts/import-collections.js wipes and imports collections.

Trade-offs

Uses express-graphql and buildSchema (SDL + rootValue resolvers) rather than Apollo Server or code-first typeDefs—lighter for learning but less tooling for subscriptions and dataloaders. No automated test suite yet. Frontend is vanilla HTML/JS for demo speed, not a production Next.js client (planned separately). GraphQL handles all CRUD except uploads, which intentionally stay REST for simpler Multer integration.

Results

A runnable blog API with role-based permissions (admin moderates comments; authors manage own drafts; users comment, like, bookmark), paginated queries, nested comment replies, view counts, and REST image uploads. Developers can explore via GraphiQL or the bundled playground, log in with seeded accounts, and walk through dashboard publish flows—making it a strong portfolio artifact for GraphQL backend and hybrid API pitches.

Key Learnings

Resolving JWT once per GraphQL request in context keeps resolvers clean and avoids repeating auth logic. Keeping uploads on REST avoids GraphQL multipart complexity while still returning URLs consumed by mutations. Pagination types duplicated per entity (ArticlePaginate, CommentPaginate) trade DRY for explicit schema clarity in a learning project. Seeding realistic relational data (authors, categories, threaded comments) makes GraphiQL demos immediately convincing.