building rest api without coding

Post on 15-Apr-2017

608 Views

Category:

Software

5 Downloads

Preview:

Click to see full reader

TRANSCRIPT

POSTGRES-

OPENRESTY

BUILDING REST API WITHOUT

PROGRAMMING

AUTHOR

Nur Agus Suryoko

PT. Virkea Empressa Sistema /

Infrastructure Architect

Living in shells from 2005; getting paid for

it from 2009

@berandajiwa

SETUP

BUILD OPENRESTY

Download openresty from: https://openresty.org/

Extract: tar -xzvf ngx_openresty-1.9.3.1.tar.gz

Configure: ./configure --with-cc-opt=“-I/usr/include”

Make: make -j 4

Install: make install

It will install at /usr/local/openresty with its own-built nginx

binary

DIRECTORIES

/usr/local/openresty the openresty home dir

/usr/local/openresty/bin resty binary

/usr/local/openresty/nginx/sbin nginx binary

/usr/local/openresty/nginx/conf nginx conf

DDL

drop table if exists posts;

create table posts (

id uuid DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL,

text varchar(255) not null,

timestamp timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,

user_id uuid REFERENCES users (id) NOT NULL,

tag JSON,

location point,

yes_count numeric(18,0),

no_count numeric(18,0)

);

drop table if exists users;

create table users (

id uuid DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL,

username varchar(255) UNIQUE NOT NULL,

email varchar(255) NOT NULL,

photo varchar(255),

location point,

registration_date timestamp without time zone DEFAULT CURRENT_TIMESTAMP,

internal_status varchar(40) NOT NULL,

short_desc text,

password text NOT NULL,

salt text,

password_status varchar(40) NOT NULL,

password_last_changed timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL

);

LET’S

START

DDL

Create the database and users:

create database ioora

Create the data structure from DDL below:

http://pastebin.com/Mi5eQyP7

NGINX.CONF

Don’t forget. The directory is: /usr/local/openresty/nginx/conf

Not the normal /etc/nginx

My complete nginx.conf: http://pastebin.com/LVsJHd6A

NGINX.CONF

Things that make it possible:

upstream database {

postgres_server 127.0.0.1 dbname=ioora user=postgres password=<your postgres password>;

}

location /posts {

postgres_pass database;

rds_json on;

postgres_query HEAD GET "SELECT * FROM posts";

postgres_query

POST "INSERT INTO posts (text, user_id) values ($arg_text, $arg_user_id)";

postgres_rewrite POST changes 201;

}

START NGINX

/usr/local/openresty/nginx/sbin/nginx

THE FIRST REST

The first REST is create a user, since no user exists in the database

curl -X POST

"http://localhost/users?username='Agus'&email='n

uragus.linux@gmail.com'&internal_status='OK'&pas

sword='Initial1'&password_status='OK'"

It’s a bit long but please bear with it. Better if you have python installed

curl -X POST

"http://localhost/users?username='Agus'&email='n

uragus.linux@gmail.com'&internal_status='OK'&pas

sword='Initial1'&password_status='OK'" | python

-m json.tool

THE RETURN

[

{

"email": "nuragus.linux@gmail.com",

"id": "ddaa3d39-bf27-474e-b28c-07980b3caaee",

"internal_status": "OK",

"location": null,

"password": "$2a$06$v4UTHYNPYodvVSHkhOddgu82Nbjj1VLZKncVdUcuJDn948/y.uY/G",

"password_last_changed": "2015-09-29 13:31:36.750245",

"password_status": "OK",

"photo": null,

"registration_date": "2015-09-29 13:31:36.750245",

"salt": null,

"short_desc": null,

"username": "Agus"

}

]

THE RETURN

Things to notice:

a. OpenResty echo the data that was just inserted to the

database

b. The password is encrypted by pgcrypt with bcrypt

c. The id is automatically generated uuid

d. Registration date and password_last_change fields are

automatically filled with current timestamp

Item b is defined in the SQL syntax in nginx.conf

Item c & d is defined in the postgresql data structure

IN THE DB

ioora=> \x on

Expanded display is on.

ioora=> select * from users;

-[ RECORD 1 ]---------+-------------------------------------------------------------

id | ddaa3d39-bf27-474e-b28c-07980b3caaee

username | Agus

email | nuragus.linux@gmail.com

photo |

location |

registration_date | 2015-09-29 13:31:36.750245

internal_status | OK

short_desc |

password | $2a$06$v4UTHYNPYodvVSHkhOddgu82Nbjj1VLZKncVdUcuJDn948/y.uY/G

salt |

password_status | OK

password_last_changed | 2015-09-29 13:31:36.750245

GET REST

This rest is displaying user:

curl "http://localhost/users" | python -m

json.tool

THE RETURN

[

{

"email": "nuragus.linux@gmail.com",

"id": "ddaa3d39-bf27-474e-b28c-07980b3caaee",

"internal_status": "OK",

"location": null,

"password": "$2a$06$v4UTHYNPYodvVSHkhOddgu82Nbjj1VLZKncVdUcuJDn948/y.uY/G",

"password_last_changed": "2015-09-29 13:31:36.750245",

"password_status": "OK",

"photo": null,

"registration_date": "2015-09-29 13:31:36.750245",

"salt": null,

"short_desc": null,

"username": "Agus"

}

]

Figures

THE RESTS

The other rest endpoints are stated in the nginx.conf files.

WHAT IT

CANNOT DO (AT LEAST CURRENTLY UNKNOWN)

CANNOT DO

Multiple SQL

We want to generate a salt, store that salt to a row, and then generate password from that salt. We can’t do that yet, unless we are using PL/PGSQL which I think kinda last resort.

Error return

The REST will return error-500 for any database error. Don’t know how to pass through error message from postgres to nginx

Authentication

The PostgreSQL username/password is hardcoded in nginx.conf. Dynamic username/password is not yet handled.

WHAT IT

GREAT AT (AT LEAST THEORITICALLY)

GREAT AT

Speed

No backend, just DB. That means extremely lightweight and

faaassst!

No coding

Even people without coding skill like me can create REST API.

What a bless!

BY THE

WAY…

top related