What is SynthQL
SynthQL is a full stack HTTP client for your PostgreSQL database. It lets you declaratively describe your React component's data dependencies.
With SynthQL you can focus on building great products instead of spending time thinking how to most efficiently fetch data into your components.
SynthQL reads your PostgreSQL database schema and generates types so you get type safety end to end.
const q = from('movies')
.columns('id', 'title', 'release_date')
.filter({ id: 1 })
.take(10);
// Execute the query
const { data: movies } = useSynthql(q);
// movies is now an array of movies with id, title and release_date
// properties
console.log(movies[0].id)
Why SynthQL?
End-to-end type safety
Generate types from your schema with a single command. Run in on your CI to ensure types are always up to date.
Read morenpx @synthql/cli generate --url $DATABASE_URL
Composable query language
Build complex queries by composing smaller queries together. The SynthQL query language is designed for easy composition and re-use.
const findPetsByOwner = (owner) =>
from('pets')
.filter({ owner })
.many();
const findPersonById = (id) => {
const pets = findPetsByOwner(id)
return from('people')
.filter({ id })
.include({ pets })
.one()
}
Built-in pagination & streaming
Pagination in SynthQL just works! You don't need to do anything special to enable it!
Read more
const query = from('users')
.filter({age: {gt:18}})
.take(100) // set the size of the page
const {data, fetchNextPage} = useSynthql(query)
Lazy queries
As queries become bigger, latency also grows. Lazy queries help you split large object graphs to optimize page load. In the following example, we use a lazy query to load a store and its products separately. This means the store can load quickly and the products can load in the background. This is especially useful when the products are not immediately visible on the page.
Read more
const products = from('products')
.column('id', 'name', 'price')
.filter({
product_id: { in: col('store.product_ids') }
})
.lazy()
.many()
const query = from('store')
.column('id', 'name')
.filter({ id })
.include({
products
})
// Over the network, this results in two JSON lines
[{ id: "store 1", name: "Fnacy store", products: { status: 'pending' } }]
[{ id: "store 1", name: "Fancy store", products: { status: "done", data: [...] } }]
Security
SynthQL offers a number of security features to help you secure your application. This includes built-in authentication, query whitelisting, and more.
Read more
const findPetsByOwner = (ownerId) => {
return from('pets')
.column('name','id')
.filter({ ownerId })
.requires('pets:read')
.many()
}
const findPersonByIds = (ids) => {
return from('people')
.column('first_name','last_name')
.requires('person:read')
.filter({id:{in:ids}})
.include({
films: findPetsByOwner(col('people.id'))
})
.many()
}
Custom query providers
Not all data comes from the database. Use custom providers to join your DB tables with data from 3rd party APIs using a predictable performance model.
Read more
const findFilmsWithRatings = () => {
const ratings = from('rotten_tomatoes_ratings')
.filter({
year:col('film.year')
})
.many()
return from('films')
.filter({ year: 1965 })
.include({ ratings })
.many()
}