parse-community/parse-server

Parse Server for Node.js / Express

21,383 stars JavaScript 10 components

Provides Parse-compatible REST API and GraphQL endpoints for mobile/web apps with database abstraction

HTTP requests enter through Express middleware that validates Parse headers and loads app configuration. Requests are routed to specific handlers (ClassesRouter for /classes, UsersRouter for /users) which create RestQuery or RestWrite objects. These objects execute database operations through DatabaseController and storage adapters, with ACL filtering and trigger execution. Responses are formatted as JSON and returned to clients, with some operations also triggering real-time updates via LiveQuery.

Under the hood, the system uses 3 feedback loops, 4 data pools, 5 control points to manage its runtime behavior.

A 10-component backend api. 373 files analyzed. Data flows through 7 distinct pipeline stages.

How Data Flows Through the System

HTTP requests enter through Express middleware that validates Parse headers and loads app configuration. Requests are routed to specific handlers (ClassesRouter for /classes, UsersRouter for /users) which create RestQuery or RestWrite objects. These objects execute database operations through DatabaseController and storage adapters, with ACL filtering and trigger execution. Responses are formatted as JSON and returned to clients, with some operations also triggering real-time updates via LiveQuery.

  1. Parse request headers — handleParseHeaders middleware extracts X-Parse-Application-Id, authentication tokens, and other Parse-specific headers, loads Config from AppCache, and creates Auth object with user permissions
  2. Route to handler — Express routes in src/Routers/ (ClassesRouter, UsersRouter, etc.) match URL patterns and HTTP methods, validate basic request structure, and delegate to appropriate handler methods [Auth]
  3. Build operation object — For queries, RestQuery constructor parses where conditions, select fields, limit/skip from request. For writes, RestWrite constructor extracts object data and validates against existing object if updating [Auth → RestQuery]
  4. Execute triggers — For writes, beforeSave triggers run first and can modify data or abort operation. For queries, beforeFind triggers can modify query parameters or return objects directly bypassing database [RestQuery → RestQuery]
  5. Execute database operation — DatabaseController translates Parse operations to adapter-specific queries (MongoDB aggregation pipelines or PostgreSQL SQL), applies ACL filtering, and executes against storage adapter [RestQuery → ParseObject]
  6. Apply transforms and ACLs — Results are filtered by ACL permissions, sensitive fields removed based on user roles, and data transformed to Parse API format with objectId, createdAt, updatedAt fields [ParseObject → ParseObject]
  7. Send response — Final results formatted as JSON response with appropriate HTTP status codes, location headers for creates, and error messages for failures [ParseObject]

Data Models

The data structures that flow between stages — the contracts that hold the system together.

ParseObject parse/node package
Plain object with className: string, objectId: string, createdAt: Date, updatedAt: Date, ACL: object, plus arbitrary user-defined fields
Created from HTTP request JSON, validated against schema, stored in database, retrieved with ACL filtering applied
RestQuery src/RestQuery.js
Object with restWhere: object (query constraints), restOptions: object (limit, skip, include, keys), className: string, auth: Auth object
Built from HTTP query parameters and request body, executed against database with ACL filtering, results transformed for response
RestWrite src/RestWrite.js
Object with className: string, query: object, data: object (fields to update), originalData: object, auth: Auth, clientSDK: object
Constructed from POST/PUT requests, validated against schema and ACLs, triggers executed, data written to database
Auth src/Auth.js
Object with config: Config, user: Parse.User, isMaster: boolean, userRoles: array, installationId: string
Created from request headers (session token, master key), user and roles loaded from database, used throughout request for permission checks
Config src/Config.js
Object with applicationId: string, masterKey: string, databaseController: DatabaseController, plus all ParseServerOptions fields
Loaded at startup from options, cached in AppCache by applicationId, retrieved for each request to access app settings
DatabaseAdapter src/Adapters/Storage/
Interface with methods find(className, schema, query, options), create(className, schema, object), update(className, schema, query, update)
Instantiated at startup with connection details, used by DatabaseController to execute all database operations

Hidden Assumptions

Things this code relies on but never validates. These are the things that cause silent failures when the system changes.

critical Environment unguarded

HTTP requests will always contain a Host header that is valid for constructing URLs - getMountForRequest() concatenates req.protocol + '://' + req.get('host') without validating that host header exists or is properly formatted

If this fails: If a malicious client omits or corrupts the Host header, config lookup fails silently returning undefined, causing all subsequent middleware to crash with 'Cannot read properties of undefined' when accessing config properties

src/middlewares.js:handleParseHeaders
critical Shape unguarded

AppCache.get(applicationId) will return an object with known structure if it returns truthy - the forEach loop assumes all cache values are either 'databaseController' or simple config properties that can be directly assigned

If this fails: If AppCache contains unexpected nested objects, circular references, or functions as values, they get assigned directly to config causing type errors or memory leaks when config is used throughout the request lifecycle

src/Config.js:Config.get
critical Ordering unguarded

The bodyparser middleware has already run before handleParseHeaders executes - comment states 'The bodyparser should run before this middleware' but there's no enforcement

If this fails: If bodyparser hasn't run, req.body is undefined causing Parse operations that expect parsed JSON data to fail with cryptic errors when trying to access request.data properties

src/middlewares.js:handleParseHeaders
warning Temporal unguarded

IP address whitelist/blocklist configuration doesn't change during server runtime - results are cached in store.set(ip, result) with no TTL or invalidation mechanism

If this fails: If administrators update IP restrictions in a running system, previously cached IP decisions persist indefinitely, allowing blocked IPs continued access or denying newly allowed IPs until server restart

src/middlewares.js:checkIp
warning Contract unguarded

Parse class objects will have either a 'className' property or a 'name' property that follows the convention of being prefixed with 'Parse' - the fallback return parseClass assumes it's already a string

If this fails: If a trigger is registered with an object that has neither property, or a name that doesn't start with 'Parse', the system returns the entire object as className causing trigger lookups to fail silently

src/triggers.js:getClassName
warning Resource weakly guarded

SQL query files exist in the expected filesystem structure relative to __dirname and are readable at startup time

If this fails: If any .sql files are missing, moved, or have wrong permissions, QueryFile constructor throws immediately causing entire server startup to fail with unclear error about missing database functionality

src/Adapters/Storage/Postgres/sql/index.js:sql
warning Scale unguarded

IP range lists (ipRangeList) contain a reasonable number of entries that can be processed synchronously during request handling without blocking the event loop

If this fails: With thousands of IP ranges, the synchronous forEach loop and BlockList.addSubnet calls can block the event loop for hundreds of milliseconds, causing request timeouts and degraded performance for all clients

src/middlewares.js:getBlockList
info Domain weakly guarded

className parameters follow the regex pattern _?[A-Za-z][A-Za-z_0-9]* which allows Parse system classes (prefixed with _) and user classes but excludes certain valid Unicode class names

If this fails: Applications using internationalized class names with Unicode characters (like Chinese or Arabic class names) will have their routes fail validation, making the API inaccessible for non-Latin class names

src/PromiseRouter.js:validateParameter
info Environment unguarded

All adapter constructors (WinstonLoggerAdapter, GridFSBucketAdapter, etc.) can be instantiated successfully with the provided options - loadAdapter() is called without try-catch

If this fails: If any adapter fails to initialize (missing dependencies, invalid config, network issues), the entire server startup fails with an unhandled exception instead of gracefully degrading or providing clear error messages

src/Controllers/index.js:getControllers
info Contract weakly guarded

Async config functions stored as this._${key} will resolve to simple values that can be assigned directly to this[key] without validation

If this fails: If an async config function like _publicServerURL returns null, undefined, or a malformed URL, it gets assigned directly to the config causing downstream URL construction to fail in REST operations or webhook callbacks

src/Config.js:Config.loadKeys

System Behavior

How the system operates at runtime — where data accumulates, what loops, what waits, and what controls what.

Data Pools

AppCache (in-memory)
Caches Parse app configurations by applicationId to avoid reloading settings on every request
Schema Cache (in-memory)
Caches database schemas to avoid repeated schema fetches during query planning and validation
User Role Cache (in-memory)
Caches user role memberships per request to avoid repeated role queries during ACL checks
LiveQuery Subscriptions (in-memory)
Stores active WebSocket subscriptions with their query filters to match against data changes

Feedback Loops

Delays

Control Points

Technology Stack

Express (framework)
HTTP server framework that handles routing, middleware, and request/response processing
MongoDB (database)
Primary database backend with aggregation pipeline support for complex Parse queries
PostgreSQL (database)
Alternative database backend using JSON columns for flexible schema support
GraphQL (library)
Alternative query interface using Apollo Server that maps to same controllers as REST API
WebSocket (library)
Real-time communication for LiveQuery subscriptions using ws library
bcrypt (library)
Password hashing for secure user authentication
jsonwebtoken (library)
JWT token generation and validation for session management
Redis (database)
Optional caching layer and rate limiting store

Key Components

Explore the interactive analysis

See the full architecture map, data flow, and code patterns visualization.

Analyze on CodeSea

Related Backend Api Repositories

Frequently Asked Questions

What is parse-server used for?

Provides Parse-compatible REST API and GraphQL endpoints for mobile/web apps with database abstraction parse-community/parse-server is a 10-component backend api written in JavaScript. Data flows through 7 distinct pipeline stages. The codebase contains 373 files.

How is parse-server architected?

parse-server is organized into 4 architecture layers: HTTP Layer, Controller Layer, Adapter Layer, GraphQL Layer. Data flows through 7 distinct pipeline stages. This layered structure keeps concerns separated and modules independent.

How does data flow through parse-server?

Data moves through 7 stages: Parse request headers → Route to handler → Build operation object → Execute triggers → Execute database operation → .... HTTP requests enter through Express middleware that validates Parse headers and loads app configuration. Requests are routed to specific handlers (ClassesRouter for /classes, UsersRouter for /users) which create RestQuery or RestWrite objects. These objects execute database operations through DatabaseController and storage adapters, with ACL filtering and trigger execution. Responses are formatted as JSON and returned to clients, with some operations also triggering real-time updates via LiveQuery. This pipeline design reflects a complex multi-stage processing system.

What technologies does parse-server use?

The core stack includes Express (HTTP server framework that handles routing, middleware, and request/response processing), MongoDB (Primary database backend with aggregation pipeline support for complex Parse queries), PostgreSQL (Alternative database backend using JSON columns for flexible schema support), GraphQL (Alternative query interface using Apollo Server that maps to same controllers as REST API), WebSocket (Real-time communication for LiveQuery subscriptions using ws library), bcrypt (Password hashing for secure user authentication), and 2 more. A focused set of dependencies that keeps the build manageable.

What system dynamics does parse-server have?

parse-server exhibits 4 data pools (AppCache, Schema Cache), 3 feedback loops, 5 control points, 3 delays. The feedback loops handle auto-scale and polling. These runtime behaviors shape how the system responds to load, failures, and configuration changes.

What design patterns does parse-server use?

5 design patterns detected: Adapter Pattern, Middleware Pipeline, Controller Facade, Registry Pattern, Observer Pattern.

Analyzed on April 20, 2026 by CodeSea. Written by .