SlideShare a Scribd company logo
Relational DB to RESTful API
Taking the database seriously
Most web frameworks treat
the DB as a dumb store
This helps give them broad
appeal
What if we take a stand
instead?
??
? ?
?
Taking the database seriously
Is PostgreSQL powerful and
flexible enough to replace
the custom API server?
That’s my experiment
The Traditional Web API Stack
Your App
Web Server
Database
The Traditional Web API Stack
Your App
Web Server
Database
PostgREST
A no-configuration canonical
mapping from DB to HTTP
Talk Overview
The Traditional API Server (brief)
Live demo of PostgREST
What’s the SQL? How did
it do that?
The Traditional App
Handmade Nested
Routes
Controllers
Imperative code
ORM
Logic divorced from
data
What’s in an app?
HTTP request handling
Authentication
Authorization
Request Parsing
Request Validation
Database Communication
Database Response Handling
HTTP Response Building
With error handling woven
throughout...
Maintaining bespoke APIs gets old
“Most APIs look the
same, some have
icing, some have
fondant, some are
vanilla, some
chocolate. At the
core they’re all still
cakes.” -- Jett
Durham
Problem 1: Boilerplate
Want to add a new route?
Create model
Add each CRUD action
Check permissions
Support filtering, pagination
Special routes for joining data
Problem 2: No Single Source of Truth
Constraints are removed
from DB
No longer enforced
continuously + uniformly
Imperative code means
human must write docs
Authorization is per-
controller rather than
Problem 3: Hierarchy
Your info is relational, your routes
hierarchical
Say projects have parts and vice
versa.
Need routes for parts by project
and project by parts?
Other people recognize the
problem, hence GraphQL
Demo Time!
We’ll use the Pagila example database
It was ported from MySQL “Sakila”
It’s a DVD store with films, rentals, customers, payments,
categories, actors etc
Security - Roles for Authorization
Anonymous Authenticator User(s)
Security - JWT for Authentication
YES
NO
Security - Roles in SQL
CREATE ROLE authenticator NOINHERIT LOGIN;
CREATE ROLE anon;
CREATE ROLE worker;
GRANT anon, worker TO authenticator;
Switching to a role
BEGIN ISOLATION LEVEL READ COMMITTED READ WRITE;
SET LOCAL ROLE 'worker';
SET LOCAL "postgrest.claims.id" = 'jdoe';
-- ...
COMMIT;
Row-Level Security
PostgreSQL 9.5+ allows restricting access to individual rows
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
drop policy if exists authors_eigenedit on posts;
create policy authors_eigenedit on posts
using (true)
with check (
author = basic_auth.current_email()
);
Let’s see it in action
External Actions
You can’t do everything
inside SQL
How do you
● Send an email?
● Call a 3rd party
service?
LISTEN / NOTIFY
How to version the API?
So far OK but… but I don’t
want to couple the internal
schema with an API!
How to encapsulate true
schema?
How to version specific
endpoints?
Use database schemas
Internal Schema V1
table1
table2
table3
view2
proc
view2
HTTP Interface is Flexible
postgrest --schema v1
postgrest --schema v2,v1
postgrest --schema v3,v2,v1
Accept: application/json;
version=2
OR
GET /v2/...
Use the schema search-path
SET search_path TO v2, v1;
How does it work inside?
Warning: Boring / Cool
Generating the payload in 100% SQL
WITH pg_source AS
(SELECT "public"."festival".* FROM "public"."festival")
SELECT
(SELECT pg_catalog.count(1) FROM "public"."festival") AS total_result_set,
pg_catalog.count(t) AS page_total,
NULL AS header,
array_to_json(array_agg(row_to_json(t)))::character VARYING AS body
FROM
(SELECT * FROM pg_source LIMIT ALL OFFSET 0) t
Adding a filter
WITH pg_source AS
(SELECT "public"."festival".* FROM "public"."festival"
WHERE "public"."festival"."name" LIKE '%fun%'::UNKNOWN)
SELECT
(SELECT pg_catalog.count(1) FROM "public"."festival"
WHERE "public"."festival"."name" LIKE '%fun%'::UNKNOWN) AS total_result_set,
pg_catalog.count(t) AS page_total,
NULL AS header,
array_to_json(array_agg(row_to_json(t)))::character varying AS body
FROM
(SELECT * FROM pg_source LIMIT ALL OFFSET 0) t
Optimistic cast
Or without a global count
WITH pg_source AS
(SELECT "public"."festival".* FROM "public"."festival")
SELECT
NULL AS total_result_set,
pg_catalog.count(t) AS page_total,
NULL AS header,
array_to_json(array_agg(row_to_json(t)))::character varying AS body
FROM
(SELECT * FROM pg_source LIMIT ALL OFFSET 0) t
Creating CSV body
-- ...
(SELECT string_agg(a.k, ',')
FROM
(SELECT json_object_keys(r)::TEXT AS k
FROM
(SELECT row_to_json(hh) AS r
FROM pg_source AS hh LIMIT 1) s
) a
) || 'n' ||
coalesce(
string_agg(
substring(t::text, 2, length(t::text) - 2), 'n'
), ''
)
-- ...
First row
Column names
Remove quotes
Embedding a relation
WITH pg_source AS
(SELECT "public"."film"."id", row_to_json("director".*) AS "director"
FROM "public"."film"
LEFT OUTER JOIN
(SELECT "public"."director".*
FROM "public"."director") AS "director"
ON "director"."name" = "film"."director")
SELECT
(SELECT pg_catalog.count(1) FROM "public"."film") AS total_result_set,
pg_catalog.count(t) AS page_total,
NULL AS header,
array_to_json(array_agg(row_to_json(t)))::character varying AS body
FROM
(SELECT * FROM pg_source LIMIT ALL OFFSET 0) t
Embed row as field
Key(s) detected
ELSE
CASE
WHEN t.typelem <> 0::oid AND t.typlen = (-1)
THEN 'ARRAY'::text
WHEN nt.nspname = 'pg_catalog'::name THEN
format_type(a.atttypid, NULL::integer)
ELSE 'USER-DEFINED'::text
END
END::information_schema.character_data AS data_type,
information_schema._pg_char_max_length(information_schema._pg_truetypid(a.*,
t.*), information_schema._pg_truetypmod(a.*,
t.*))::information_schema.cardinal_number AS character_maximum_length,
information_schema._pg_char_octet_length(information_schema._pg_truetypid(a.
*, t.*), information_schema._pg_truetypmod(a.*,
t.*))::information_schema.cardinal_number AS character_octet_length,
information_schema._pg_numeric_precision(information_schema._pg_truetypid(a.
*, t.*), information_schema._pg_truetypmod(a.*,
t.*))::information_schema.cardinal_number AS numeric_precision,
information_schema._pg_numeric_precision_radix(information_schema._pg_truety
pid(a.*, t.*), information_schema._pg_truetypmod(a.*,
t.*))::information_schema.cardinal_number AS numeric_precision_radix,
information_schema._pg_numeric_scale(information_schema._pg_truetypid(a.*,
t.*), information_schema._pg_truetypmod(a.*,
t.*))::information_schema.cardinal_number AS numeric_scale,
information_schema._pg_datetime_precision(information_schema._pg_truetypid(a
.*, t.*), information_schema._pg_truetypmod(a.*,
t.*))::information_schema.cardinal_number AS datetime_precision,
information_schema._pg_interval_type(information_schema._pg_truetypid(a.*,
t.*), information_schema._pg_truetypmod(a.*,
t.*))::information_schema.character_data AS interval_type,
NULL::integer::information_schema.cardinal_number AS
interval_precision,
NULL::character varying::information_schema.sql_identifier
AS character_set_catalog,
NULL::character varying::information_schema.sql_identifier
AS character_set_schema,
NULL::character varying::information_schema.sql_identifier
AS character_set_name,
SELECT DISTINCT
info.table_schema AS schema,
info.table_name AS table_name,
info.column_name AS name,
info.ordinal_position AS position,
info.is_nullable::boolean AS nullable,
info.data_type AS col_type,
info.is_updatable::boolean AS updatable,
info.character_maximum_length AS max_len,
info.numeric_precision AS precision,
info.column_default AS default_value,
array_to_string(enum_info.vals, ',') AS enum
FROM (
/*
-- CTE based on information_schema.columns to remove the owner filter
*/
WITH columns AS (
SELECT current_database()::information_schema.sql_identifier AS table_catalog,
nc.nspname::information_schema.sql_identifier AS table_schema,
c.relname::information_schema.sql_identifier AS table_name,
a.attname::information_schema.sql_identifier AS column_name,
a.attnum::information_schema.cardinal_number AS ordinal_position,
pg_get_expr(ad.adbin, ad.adrelid)::information_schema.character_data AS column_default,
CASE
WHEN a.attnotnull OR t.typtype = 'd'::"char" AND t.typnotnull THEN 'NO'::text
ELSE 'YES'::text
END::information_schema.yes_or_no AS is_nullable,
CASE
WHEN t.typtype = 'd'::"char" THEN
CASE
WHEN bt.typelem <> 0::oid AND bt.typlen = (-1) THEN 'ARRAY'::text
WHEN nbt.nspname = 'pg_catalog'::name THEN format_type(t.typbasetype,
NULL::integer)
ELSE 'USER-DEFINED'::text
END
Matching up foreign keys
Deleting an item
WITH pg_source AS
(DELETE FROM "test"."items"
WHERE "test"."items"."id" = '1'::unknown
RETURNING "test"."items".*)
SELECT
'' AS total_result_set,
pg_catalog.count(t) AS page_total,
'',
''
FROM
(SELECT 1 FROM pg_source) t
Learning More
Read the Docs
http://postgrest.com
github.com / begriffs / postgrest

More Related Content

What's hot

Jim Dowling - Multi-tenant Flink-as-a-Service on YARN
Jim Dowling - Multi-tenant Flink-as-a-Service on YARN Jim Dowling - Multi-tenant Flink-as-a-Service on YARN
Jim Dowling - Multi-tenant Flink-as-a-Service on YARN Flink Forward
 
2019 06-12-aws taipei summit-dev day-essential capabilities behind microservices
2019 06-12-aws taipei summit-dev day-essential capabilities behind microservices2019 06-12-aws taipei summit-dev day-essential capabilities behind microservices
2019 06-12-aws taipei summit-dev day-essential capabilities behind microservicesKim Kao
 
[백서] Google 드라이브에서 다운로드 방지할수 있을까
[백서] Google 드라이브에서 다운로드 방지할수 있을까 [백서] Google 드라이브에서 다운로드 방지할수 있을까
[백서] Google 드라이브에서 다운로드 방지할수 있을까 Charly Choi
 
Develop QNAP NAS App by Docker
Develop QNAP NAS App by DockerDevelop QNAP NAS App by Docker
Develop QNAP NAS App by DockerTerry Chen
 
Apache Kafka: A high-throughput distributed messaging system @ JCConf 2014
Apache Kafka: A high-throughput distributed messaging system @ JCConf 2014Apache Kafka: A high-throughput distributed messaging system @ JCConf 2014
Apache Kafka: A high-throughput distributed messaging system @ JCConf 2014Chen-en Lu
 
Accelerating Hyper-Converged Enterprise Virtualization using Proxmox and Ceph
Accelerating Hyper-Converged Enterprise Virtualization using Proxmox and CephAccelerating Hyper-Converged Enterprise Virtualization using Proxmox and Ceph
Accelerating Hyper-Converged Enterprise Virtualization using Proxmox and CephBangladesh Network Operators Group
 
Event Driven Architecture (EDA) Reference Architecture | Anbu Krishnaswamy
Event Driven Architecture (EDA) Reference Architecture | Anbu KrishnaswamyEvent Driven Architecture (EDA) Reference Architecture | Anbu Krishnaswamy
Event Driven Architecture (EDA) Reference Architecture | Anbu KrishnaswamyBob Rhubart
 
Kafka Tutorial - introduction to the Kafka streaming platform
Kafka Tutorial - introduction to the Kafka streaming platformKafka Tutorial - introduction to the Kafka streaming platform
Kafka Tutorial - introduction to the Kafka streaming platformJean-Paul Azar
 
Quick Start to Field Service Lightning, Paweł Dobrzynski
Quick Start to Field Service Lightning, Paweł DobrzynskiQuick Start to Field Service Lightning, Paweł Dobrzynski
Quick Start to Field Service Lightning, Paweł DobrzynskiCzechDreamin
 
Implementing Domain Events with Kafka
Implementing Domain Events with KafkaImplementing Domain Events with Kafka
Implementing Domain Events with KafkaAndrei Rugina
 
DoK Talks #91- Leveraging Druid Operator to manage Apache Druid on Kubernetes
DoK Talks #91- Leveraging Druid Operator to manage Apache Druid on KubernetesDoK Talks #91- Leveraging Druid Operator to manage Apache Druid on Kubernetes
DoK Talks #91- Leveraging Druid Operator to manage Apache Druid on KubernetesDoKC
 
Integration Microservices
Integration MicroservicesIntegration Microservices
Integration MicroservicesKasun Indrasiri
 
Real Time Integration with Salesforce Platform Events
Real Time Integration with Salesforce Platform EventsReal Time Integration with Salesforce Platform Events
Real Time Integration with Salesforce Platform EventsSalesforce Developers
 
Mule expression language
Mule expression languageMule expression language
Mule expression languagesathyaraj Anand
 
Alpha BIM Plugin | Formwork Area Guideline | Revit API
Alpha BIM Plugin | Formwork Area Guideline | Revit APIAlpha BIM Plugin | Formwork Area Guideline | Revit API
Alpha BIM Plugin | Formwork Area Guideline | Revit APIDangLeQuan1
 
Introducing the Apache Flink Kubernetes Operator
Introducing the Apache Flink Kubernetes OperatorIntroducing the Apache Flink Kubernetes Operator
Introducing the Apache Flink Kubernetes OperatorFlink Forward
 
Squirreling Away $640 Billion: How Stripe Leverages Flink for Change Data Cap...
Squirreling Away $640 Billion: How Stripe Leverages Flink for Change Data Cap...Squirreling Away $640 Billion: How Stripe Leverages Flink for Change Data Cap...
Squirreling Away $640 Billion: How Stripe Leverages Flink for Change Data Cap...Flink Forward
 
Event-driven Microservices with Python and Apache Kafka with Dave Klein | Ka...
Event-driven Microservices with Python and Apache Kafka with Dave Klein  | Ka...Event-driven Microservices with Python and Apache Kafka with Dave Klein  | Ka...
Event-driven Microservices with Python and Apache Kafka with Dave Klein | Ka...HostedbyConfluent
 

What's hot (20)

Jim Dowling - Multi-tenant Flink-as-a-Service on YARN
Jim Dowling - Multi-tenant Flink-as-a-Service on YARN Jim Dowling - Multi-tenant Flink-as-a-Service on YARN
Jim Dowling - Multi-tenant Flink-as-a-Service on YARN
 
2019 06-12-aws taipei summit-dev day-essential capabilities behind microservices
2019 06-12-aws taipei summit-dev day-essential capabilities behind microservices2019 06-12-aws taipei summit-dev day-essential capabilities behind microservices
2019 06-12-aws taipei summit-dev day-essential capabilities behind microservices
 
Oracle OSB Tutorial 2
Oracle OSB Tutorial 2Oracle OSB Tutorial 2
Oracle OSB Tutorial 2
 
[백서] Google 드라이브에서 다운로드 방지할수 있을까
[백서] Google 드라이브에서 다운로드 방지할수 있을까 [백서] Google 드라이브에서 다운로드 방지할수 있을까
[백서] Google 드라이브에서 다운로드 방지할수 있을까
 
Develop QNAP NAS App by Docker
Develop QNAP NAS App by DockerDevelop QNAP NAS App by Docker
Develop QNAP NAS App by Docker
 
Apache Kafka: A high-throughput distributed messaging system @ JCConf 2014
Apache Kafka: A high-throughput distributed messaging system @ JCConf 2014Apache Kafka: A high-throughput distributed messaging system @ JCConf 2014
Apache Kafka: A high-throughput distributed messaging system @ JCConf 2014
 
Accelerating Hyper-Converged Enterprise Virtualization using Proxmox and Ceph
Accelerating Hyper-Converged Enterprise Virtualization using Proxmox and CephAccelerating Hyper-Converged Enterprise Virtualization using Proxmox and Ceph
Accelerating Hyper-Converged Enterprise Virtualization using Proxmox and Ceph
 
APEX Themes and Templates
APEX Themes and TemplatesAPEX Themes and Templates
APEX Themes and Templates
 
Event Driven Architecture (EDA) Reference Architecture | Anbu Krishnaswamy
Event Driven Architecture (EDA) Reference Architecture | Anbu KrishnaswamyEvent Driven Architecture (EDA) Reference Architecture | Anbu Krishnaswamy
Event Driven Architecture (EDA) Reference Architecture | Anbu Krishnaswamy
 
Kafka Tutorial - introduction to the Kafka streaming platform
Kafka Tutorial - introduction to the Kafka streaming platformKafka Tutorial - introduction to the Kafka streaming platform
Kafka Tutorial - introduction to the Kafka streaming platform
 
Quick Start to Field Service Lightning, Paweł Dobrzynski
Quick Start to Field Service Lightning, Paweł DobrzynskiQuick Start to Field Service Lightning, Paweł Dobrzynski
Quick Start to Field Service Lightning, Paweł Dobrzynski
 
Implementing Domain Events with Kafka
Implementing Domain Events with KafkaImplementing Domain Events with Kafka
Implementing Domain Events with Kafka
 
DoK Talks #91- Leveraging Druid Operator to manage Apache Druid on Kubernetes
DoK Talks #91- Leveraging Druid Operator to manage Apache Druid on KubernetesDoK Talks #91- Leveraging Druid Operator to manage Apache Druid on Kubernetes
DoK Talks #91- Leveraging Druid Operator to manage Apache Druid on Kubernetes
 
Integration Microservices
Integration MicroservicesIntegration Microservices
Integration Microservices
 
Real Time Integration with Salesforce Platform Events
Real Time Integration with Salesforce Platform EventsReal Time Integration with Salesforce Platform Events
Real Time Integration with Salesforce Platform Events
 
Mule expression language
Mule expression languageMule expression language
Mule expression language
 
Alpha BIM Plugin | Formwork Area Guideline | Revit API
Alpha BIM Plugin | Formwork Area Guideline | Revit APIAlpha BIM Plugin | Formwork Area Guideline | Revit API
Alpha BIM Plugin | Formwork Area Guideline | Revit API
 
Introducing the Apache Flink Kubernetes Operator
Introducing the Apache Flink Kubernetes OperatorIntroducing the Apache Flink Kubernetes Operator
Introducing the Apache Flink Kubernetes Operator
 
Squirreling Away $640 Billion: How Stripe Leverages Flink for Change Data Cap...
Squirreling Away $640 Billion: How Stripe Leverages Flink for Change Data Cap...Squirreling Away $640 Billion: How Stripe Leverages Flink for Change Data Cap...
Squirreling Away $640 Billion: How Stripe Leverages Flink for Change Data Cap...
 
Event-driven Microservices with Python and Apache Kafka with Dave Klein | Ka...
Event-driven Microservices with Python and Apache Kafka with Dave Klein  | Ka...Event-driven Microservices with Python and Apache Kafka with Dave Klein  | Ka...
Event-driven Microservices with Python and Apache Kafka with Dave Klein | Ka...
 

Similar to A Tour of PostgREST

SQL Server - Introduction to TSQL
SQL Server - Introduction to TSQLSQL Server - Introduction to TSQL
SQL Server - Introduction to TSQLPeter Gfader
 
Expanding your impact with programmability in the data center
Expanding your impact with programmability in the data centerExpanding your impact with programmability in the data center
Expanding your impact with programmability in the data centerCisco Canada
 
Oracle to Amazon Aurora Migration, Step by Step - AWS Online Tech Talks
Oracle to Amazon Aurora Migration, Step by Step - AWS Online Tech TalksOracle to Amazon Aurora Migration, Step by Step - AWS Online Tech Talks
Oracle to Amazon Aurora Migration, Step by Step - AWS Online Tech TalksAmazon Web Services
 
닷넷 개발자를 위한 패턴이야기
닷넷 개발자를 위한 패턴이야기닷넷 개발자를 위한 패턴이야기
닷넷 개발자를 위한 패턴이야기YoungSu Son
 
Seattle StrongLoop Node.js Workshop
Seattle StrongLoop Node.js WorkshopSeattle StrongLoop Node.js Workshop
Seattle StrongLoop Node.js WorkshopJimmy Guerrero
 
The 90-Day Startup with Google AppEngine for Java
The 90-Day Startup with Google AppEngine for JavaThe 90-Day Startup with Google AppEngine for Java
The 90-Day Startup with Google AppEngine for JavaDavid Chandler
 
OWB11gR2 - Extending ETL
OWB11gR2 - Extending ETL OWB11gR2 - Extending ETL
OWB11gR2 - Extending ETL Suraj Bang
 
Python RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutionsPython RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutionsSolution4Future
 
Porting Applications From Oracle To PostgreSQL
Porting Applications From Oracle To PostgreSQLPorting Applications From Oracle To PostgreSQL
Porting Applications From Oracle To PostgreSQLPeter Eisentraut
 
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...Fwdays
 
[db tech showcase Tokyo 2017] C23: Lessons from SQLite4 by SQLite.org - Richa...
[db tech showcase Tokyo 2017] C23: Lessons from SQLite4 by SQLite.org - Richa...[db tech showcase Tokyo 2017] C23: Lessons from SQLite4 by SQLite.org - Richa...
[db tech showcase Tokyo 2017] C23: Lessons from SQLite4 by SQLite.org - Richa...Insight Technology, Inc.
 
Engage 2023: Taking Domino Apps to the next level by providing a Rest API
Engage 2023: Taking Domino Apps to the next level by providing a Rest APIEngage 2023: Taking Domino Apps to the next level by providing a Rest API
Engage 2023: Taking Domino Apps to the next level by providing a Rest APISerdar Basegmez
 
Javazone 2010-lift-framework-public
Javazone 2010-lift-framework-publicJavazone 2010-lift-framework-public
Javazone 2010-lift-framework-publicTimothy Perrett
 
Choisir entre une API RPC, SOAP, REST, GraphQL? 
Et si le problème était ai...
Choisir entre une API  RPC, SOAP, REST, GraphQL?  
Et si le problème était ai...Choisir entre une API  RPC, SOAP, REST, GraphQL?  
Et si le problème était ai...
Choisir entre une API RPC, SOAP, REST, GraphQL? 
Et si le problème était ai...François-Guillaume Ribreau
 
Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...
Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...
Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...NoSQLmatters
 
Postgres Vienna DB Meetup 2014
Postgres Vienna DB Meetup 2014Postgres Vienna DB Meetup 2014
Postgres Vienna DB Meetup 2014Michael Renner
 

Similar to A Tour of PostgREST (20)

SQL Server - Introduction to TSQL
SQL Server - Introduction to TSQLSQL Server - Introduction to TSQL
SQL Server - Introduction to TSQL
 
Expanding your impact with programmability in the data center
Expanding your impact with programmability in the data centerExpanding your impact with programmability in the data center
Expanding your impact with programmability in the data center
 
Oracle to Amazon Aurora Migration, Step by Step - AWS Online Tech Talks
Oracle to Amazon Aurora Migration, Step by Step - AWS Online Tech TalksOracle to Amazon Aurora Migration, Step by Step - AWS Online Tech Talks
Oracle to Amazon Aurora Migration, Step by Step - AWS Online Tech Talks
 
Switch to Backend 2023
Switch to Backend 2023Switch to Backend 2023
Switch to Backend 2023
 
닷넷 개발자를 위한 패턴이야기
닷넷 개발자를 위한 패턴이야기닷넷 개발자를 위한 패턴이야기
닷넷 개발자를 위한 패턴이야기
 
Seattle StrongLoop Node.js Workshop
Seattle StrongLoop Node.js WorkshopSeattle StrongLoop Node.js Workshop
Seattle StrongLoop Node.js Workshop
 
Jdbc
JdbcJdbc
Jdbc
 
The 90-Day Startup with Google AppEngine for Java
The 90-Day Startup with Google AppEngine for JavaThe 90-Day Startup with Google AppEngine for Java
The 90-Day Startup with Google AppEngine for Java
 
Plproxy
PlproxyPlproxy
Plproxy
 
PPT
PPTPPT
PPT
 
OWB11gR2 - Extending ETL
OWB11gR2 - Extending ETL OWB11gR2 - Extending ETL
OWB11gR2 - Extending ETL
 
Python RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutionsPython RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutions
 
Porting Applications From Oracle To PostgreSQL
Porting Applications From Oracle To PostgreSQLPorting Applications From Oracle To PostgreSQL
Porting Applications From Oracle To PostgreSQL
 
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
 
[db tech showcase Tokyo 2017] C23: Lessons from SQLite4 by SQLite.org - Richa...
[db tech showcase Tokyo 2017] C23: Lessons from SQLite4 by SQLite.org - Richa...[db tech showcase Tokyo 2017] C23: Lessons from SQLite4 by SQLite.org - Richa...
[db tech showcase Tokyo 2017] C23: Lessons from SQLite4 by SQLite.org - Richa...
 
Engage 2023: Taking Domino Apps to the next level by providing a Rest API
Engage 2023: Taking Domino Apps to the next level by providing a Rest APIEngage 2023: Taking Domino Apps to the next level by providing a Rest API
Engage 2023: Taking Domino Apps to the next level by providing a Rest API
 
Javazone 2010-lift-framework-public
Javazone 2010-lift-framework-publicJavazone 2010-lift-framework-public
Javazone 2010-lift-framework-public
 
Choisir entre une API RPC, SOAP, REST, GraphQL? 
Et si le problème était ai...
Choisir entre une API  RPC, SOAP, REST, GraphQL?  
Et si le problème était ai...Choisir entre une API  RPC, SOAP, REST, GraphQL?  
Et si le problème était ai...
Choisir entre une API RPC, SOAP, REST, GraphQL? 
Et si le problème était ai...
 
Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...
Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...
Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...
 
Postgres Vienna DB Meetup 2014
Postgres Vienna DB Meetup 2014Postgres Vienna DB Meetup 2014
Postgres Vienna DB Meetup 2014
 

Recently uploaded

How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...Product School
 
In-Depth Performance Testing Guide for IT Professionals
In-Depth Performance Testing Guide for IT ProfessionalsIn-Depth Performance Testing Guide for IT Professionals
In-Depth Performance Testing Guide for IT ProfessionalsExpeed Software
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backElena Simperl
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupCatarinaPereira64715
 
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxDavid Michel
 
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...CzechDreamin
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Product School
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersSafe Software
 
Optimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityOptimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityScyllaDB
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Product School
 
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...CzechDreamin
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Thierry Lestable
 
UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1DianaGray10
 
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCustom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCzechDreamin
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...Sri Ambati
 
AI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekAI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekCzechDreamin
 
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Julian Hyde
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3DianaGray10
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...Product School
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxAbida Shariff
 

Recently uploaded (20)

How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
In-Depth Performance Testing Guide for IT Professionals
In-Depth Performance Testing Guide for IT ProfessionalsIn-Depth Performance Testing Guide for IT Professionals
In-Depth Performance Testing Guide for IT Professionals
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
 
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
 
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
Optimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityOptimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through Observability
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1
 
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCustom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
AI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekAI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří Karpíšek
 
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 

A Tour of PostgREST

  • 1. Relational DB to RESTful API
  • 2. Taking the database seriously Most web frameworks treat the DB as a dumb store This helps give them broad appeal What if we take a stand instead? ?? ? ? ?
  • 3. Taking the database seriously Is PostgreSQL powerful and flexible enough to replace the custom API server? That’s my experiment
  • 4. The Traditional Web API Stack Your App Web Server Database
  • 5. The Traditional Web API Stack Your App Web Server Database PostgREST A no-configuration canonical mapping from DB to HTTP
  • 6. Talk Overview The Traditional API Server (brief) Live demo of PostgREST What’s the SQL? How did it do that?
  • 7. The Traditional App Handmade Nested Routes Controllers Imperative code ORM Logic divorced from data
  • 8. What’s in an app? HTTP request handling Authentication Authorization Request Parsing Request Validation Database Communication Database Response Handling HTTP Response Building With error handling woven throughout...
  • 9. Maintaining bespoke APIs gets old “Most APIs look the same, some have icing, some have fondant, some are vanilla, some chocolate. At the core they’re all still cakes.” -- Jett Durham
  • 10. Problem 1: Boilerplate Want to add a new route? Create model Add each CRUD action Check permissions Support filtering, pagination Special routes for joining data
  • 11. Problem 2: No Single Source of Truth Constraints are removed from DB No longer enforced continuously + uniformly Imperative code means human must write docs Authorization is per- controller rather than
  • 12. Problem 3: Hierarchy Your info is relational, your routes hierarchical Say projects have parts and vice versa. Need routes for parts by project and project by parts? Other people recognize the problem, hence GraphQL
  • 13. Demo Time! We’ll use the Pagila example database It was ported from MySQL “Sakila” It’s a DVD store with films, rentals, customers, payments, categories, actors etc
  • 14.
  • 15. Security - Roles for Authorization Anonymous Authenticator User(s)
  • 16. Security - JWT for Authentication YES NO
  • 17. Security - Roles in SQL CREATE ROLE authenticator NOINHERIT LOGIN; CREATE ROLE anon; CREATE ROLE worker; GRANT anon, worker TO authenticator;
  • 18. Switching to a role BEGIN ISOLATION LEVEL READ COMMITTED READ WRITE; SET LOCAL ROLE 'worker'; SET LOCAL "postgrest.claims.id" = 'jdoe'; -- ... COMMIT;
  • 19. Row-Level Security PostgreSQL 9.5+ allows restricting access to individual rows ALTER TABLE posts ENABLE ROW LEVEL SECURITY; drop policy if exists authors_eigenedit on posts; create policy authors_eigenedit on posts using (true) with check ( author = basic_auth.current_email() );
  • 20. Let’s see it in action
  • 21. External Actions You can’t do everything inside SQL How do you ● Send an email? ● Call a 3rd party service? LISTEN / NOTIFY
  • 22. How to version the API? So far OK but… but I don’t want to couple the internal schema with an API! How to encapsulate true schema? How to version specific endpoints?
  • 23. Use database schemas Internal Schema V1 table1 table2 table3 view2 proc view2
  • 24. HTTP Interface is Flexible postgrest --schema v1 postgrest --schema v2,v1 postgrest --schema v3,v2,v1 Accept: application/json; version=2 OR GET /v2/...
  • 25. Use the schema search-path SET search_path TO v2, v1;
  • 26. How does it work inside? Warning: Boring / Cool
  • 27. Generating the payload in 100% SQL WITH pg_source AS (SELECT "public"."festival".* FROM "public"."festival") SELECT (SELECT pg_catalog.count(1) FROM "public"."festival") AS total_result_set, pg_catalog.count(t) AS page_total, NULL AS header, array_to_json(array_agg(row_to_json(t)))::character VARYING AS body FROM (SELECT * FROM pg_source LIMIT ALL OFFSET 0) t
  • 28. Adding a filter WITH pg_source AS (SELECT "public"."festival".* FROM "public"."festival" WHERE "public"."festival"."name" LIKE '%fun%'::UNKNOWN) SELECT (SELECT pg_catalog.count(1) FROM "public"."festival" WHERE "public"."festival"."name" LIKE '%fun%'::UNKNOWN) AS total_result_set, pg_catalog.count(t) AS page_total, NULL AS header, array_to_json(array_agg(row_to_json(t)))::character varying AS body FROM (SELECT * FROM pg_source LIMIT ALL OFFSET 0) t Optimistic cast
  • 29. Or without a global count WITH pg_source AS (SELECT "public"."festival".* FROM "public"."festival") SELECT NULL AS total_result_set, pg_catalog.count(t) AS page_total, NULL AS header, array_to_json(array_agg(row_to_json(t)))::character varying AS body FROM (SELECT * FROM pg_source LIMIT ALL OFFSET 0) t
  • 30. Creating CSV body -- ... (SELECT string_agg(a.k, ',') FROM (SELECT json_object_keys(r)::TEXT AS k FROM (SELECT row_to_json(hh) AS r FROM pg_source AS hh LIMIT 1) s ) a ) || 'n' || coalesce( string_agg( substring(t::text, 2, length(t::text) - 2), 'n' ), '' ) -- ... First row Column names Remove quotes
  • 31. Embedding a relation WITH pg_source AS (SELECT "public"."film"."id", row_to_json("director".*) AS "director" FROM "public"."film" LEFT OUTER JOIN (SELECT "public"."director".* FROM "public"."director") AS "director" ON "director"."name" = "film"."director") SELECT (SELECT pg_catalog.count(1) FROM "public"."film") AS total_result_set, pg_catalog.count(t) AS page_total, NULL AS header, array_to_json(array_agg(row_to_json(t)))::character varying AS body FROM (SELECT * FROM pg_source LIMIT ALL OFFSET 0) t Embed row as field Key(s) detected
  • 32. ELSE CASE WHEN t.typelem <> 0::oid AND t.typlen = (-1) THEN 'ARRAY'::text WHEN nt.nspname = 'pg_catalog'::name THEN format_type(a.atttypid, NULL::integer) ELSE 'USER-DEFINED'::text END END::information_schema.character_data AS data_type, information_schema._pg_char_max_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS character_maximum_length, information_schema._pg_char_octet_length(information_schema._pg_truetypid(a. *, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS character_octet_length, information_schema._pg_numeric_precision(information_schema._pg_truetypid(a. *, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS numeric_precision, information_schema._pg_numeric_precision_radix(information_schema._pg_truety pid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS numeric_precision_radix, information_schema._pg_numeric_scale(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS numeric_scale, information_schema._pg_datetime_precision(information_schema._pg_truetypid(a .*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS datetime_precision, information_schema._pg_interval_type(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.character_data AS interval_type, NULL::integer::information_schema.cardinal_number AS interval_precision, NULL::character varying::information_schema.sql_identifier AS character_set_catalog, NULL::character varying::information_schema.sql_identifier AS character_set_schema, NULL::character varying::information_schema.sql_identifier AS character_set_name, SELECT DISTINCT info.table_schema AS schema, info.table_name AS table_name, info.column_name AS name, info.ordinal_position AS position, info.is_nullable::boolean AS nullable, info.data_type AS col_type, info.is_updatable::boolean AS updatable, info.character_maximum_length AS max_len, info.numeric_precision AS precision, info.column_default AS default_value, array_to_string(enum_info.vals, ',') AS enum FROM ( /* -- CTE based on information_schema.columns to remove the owner filter */ WITH columns AS ( SELECT current_database()::information_schema.sql_identifier AS table_catalog, nc.nspname::information_schema.sql_identifier AS table_schema, c.relname::information_schema.sql_identifier AS table_name, a.attname::information_schema.sql_identifier AS column_name, a.attnum::information_schema.cardinal_number AS ordinal_position, pg_get_expr(ad.adbin, ad.adrelid)::information_schema.character_data AS column_default, CASE WHEN a.attnotnull OR t.typtype = 'd'::"char" AND t.typnotnull THEN 'NO'::text ELSE 'YES'::text END::information_schema.yes_or_no AS is_nullable, CASE WHEN t.typtype = 'd'::"char" THEN CASE WHEN bt.typelem <> 0::oid AND bt.typlen = (-1) THEN 'ARRAY'::text WHEN nbt.nspname = 'pg_catalog'::name THEN format_type(t.typbasetype, NULL::integer) ELSE 'USER-DEFINED'::text END Matching up foreign keys
  • 33. Deleting an item WITH pg_source AS (DELETE FROM "test"."items" WHERE "test"."items"."id" = '1'::unknown RETURNING "test"."items".*) SELECT '' AS total_result_set, pg_catalog.count(t) AS page_total, '', '' FROM (SELECT 1 FROM pg_source) t
  • 34. Learning More Read the Docs http://postgrest.com
  • 35. github.com / begriffs / postgrest