For Developers

Build APIs the way you think about data

Your Problem

You're tired of:

  • Writing field resolvers for every relationship
  • Fighting N+1 queries with DataLoaders
  • Debugging why a simple query runs 50 database hits
  • Spending more time optimizing than building features

You know SQL. You understand your database. You just want to serve it as GraphQL.

What FraiseQL Gives You

✅ Think in SQL

Write SQL views. Compose JSONB. You understand exactly what's happening.

No magic. No ORM generating queries you didn't ask for.

✅ Map to Types

Define types in your language. FraiseQL validates that types match views.

# Your schema matches your database
@fraiseql.type
class User:
  id: ID
  name: str
  email: str

✅ No Field Resolvers

No per-field queries. No N+1 prevention logic. Just queries and mutations.

# One query. One database hit. Done.
@fraiseql.query(sql_source="v_user")
def user(id: ID) -> User:
  pass

✅ Deploy with Confidence

Views compile at deploy time. Errors caught before production.

No runtime schema interpretation. Just execute.

How FraiseQL vs Traditional GraphQL

❌ Traditional GraphQL

# Fetch user
@resolver
async def user(info, id) -> User:
  return db.find_user(id)

# Fetch user + posts (needs resolver)
@resolver
async def posts(parent, info) -> List[Post]:
  posts = db.find_posts(parent.id)  # Separate query!
  return posts

# Result: N+1 problem
# 1 user query + 1 posts query per user = 1 + N queries

✅ FraiseQL

# SQL view pre-composes everything
CREATE VIEW v_user_with_posts AS
SELECT id, jsonb_build_object(
  'name', name,
  'posts', (SELECT jsonb_agg(...))
) AS data
FROM tb_user;

# Single resolver
@fraiseql.query(sql_source="v_user_with_posts")
def user(id: ID) -> User:
  pass

# Result: 1 query for user + posts

Your Learning Path

1

Start: 10 minutes

Read the Getting Started guide. Write your first view and schema.

Get Started →
2

Understand: 20 minutes

Learn how FraiseQL works under the hood and why it's different.

How It Works →
3

Think: 30 minutes

Explore the philosophy. Why database-first? Why CQRS? Why compilation?

Philosophy →
4

Build: 1-2 hours

Create your first real project. Start simple, add complexity.

See Examples →

What You Can Build

REST → GraphQL Migration

Have a REST API? Add GraphQL without rewriting everything.

Define views for existing tables. Map to types. Done.

Dashboards & Analytics

Complex queries with multiple tables? Pre-compose in views.

Serve aggregations as GraphQL.

Real-time APIs

Use subscriptions on top of pre-composed views.

Performance scales naturally.

Multi-tenant SaaS

Filter at database level with views.

Security and performance in one place.

Mobile Backends

Mobile apps need efficient APIs. FraiseQL delivers.

One query per request. Minimal bandwidth.

Complex Relationships

Posts with comments, likes, author info?

Compose once in views. Query once from API.

Choose Your Language

Python

Most popular for data work

@fraiseql.query(sql_source="v_users")
def users(limit: int = 100) -> list[User]:
  pass

TypeScript

Full type safety in Node

@fraiseqlQuery({ sqlSource: "v_users" })
function users(limit: number = 100): User[] {
  // authoring only
}

Go

Performance and simplicity

func (r *Query) Users(ctx context.Context) ([]*User, error) {
  // authoring only
}

PHP

For existing PHP backends

#[FraiseQLQuery(sqlSource: "v_users")]
function users(int $limit = 100): array {
  // authoring only
}

Works With Your Stack

Databases

  • PostgreSQL
  • MySQL / MariaDB
  • SQLite

Authentication

  • Auth0
  • Firebase
  • Clerk
  • Custom JWT

Caching

  • Redis
  • Memcached
  • In-memory

Deployment

  • Docker
  • Kubernetes
  • Railway
  • Fly.io
  • AWS

Common Questions

Q: How long to learn?

A: 10-30 minutes to understand. 1-2 hours to build something real. You already know SQL and your language.

Q: Can I use existing databases?

A: Yes! Add views to your existing schema. No migration needed.

Q: What about complex logic?

A: Compose data in views. Implement logic in SQL functions (fn_*) that back your mutations — the database is where the logic lives.

Q: How do I debug?

A: Views are SQL. Run EXPLAIN ANALYZE to see query plans. One query per request means clear debugging.

Q: Is it production-ready?

A: Yes. Used in production at several companies. Compile-time validation means fewer bugs.

Ready to Start?