From 6382b597fad39f4bff404260e0659accefffb92a Mon Sep 17 00:00:00 2001 From: Joe Nelson Date: Sun, 2 Jul 2017 21:17:49 -0500 Subject: [PATCH] Zeroeth tutorial --- _static/tuts/tut0-request-flow.png | Bin 0 -> 16696 bytes admin.rst | 2 + conf.py | 4 +- index.rst | 5 + install.rst | 2 + tutorials/tut0.rst | 214 +++++++++++++++++++++++++++++ 6 files changed, 225 insertions(+), 2 deletions(-) create mode 100644 _static/tuts/tut0-request-flow.png create mode 100644 tutorials/tut0.rst diff --git a/_static/tuts/tut0-request-flow.png b/_static/tuts/tut0-request-flow.png new file mode 100644 index 0000000000000000000000000000000000000000..24f2986e81ae431f8e0ab1366ca65d6266ffcad9 GIT binary patch literal 16696 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 J);T3K0RUG}=RE)b literal 0 HcmV?d00001 diff --git a/admin.rst b/admin.rst index a1abf9cc9..ae7b1ab20 100644 --- a/admin.rst +++ b/admin.rst @@ -1,3 +1,5 @@ +.. _configuration: + Configuration ============= diff --git a/conf.py b/conf.py index 479232894..415ce36c2 100644 --- a/conf.py +++ b/conf.py @@ -54,9 +54,9 @@ author = u'Joe Nelson' # built documents. # # The short X.Y version. -version = u'0.4' +version = u'4.1' # The full version, including alpha/beta/rc tags. -release = u'0.4.0.0' +release = u'4.1.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/index.rst b/index.rst index 85935f068..28fa94a09 100644 --- a/index.rst +++ b/index.rst @@ -10,6 +10,11 @@ intro.rst +.. toctree:: + :caption: Tutorials + + tutorials/tut0.rst + .. toctree:: :caption: Installation diff --git a/install.rst b/install.rst index f1bb74f77..100496314 100644 --- a/install.rst +++ b/install.rst @@ -49,6 +49,8 @@ To use PostgREST you will need an underlying database (PostgreSQL version 9.3 or * `Instructions for Ubuntu 14.04 `_ * `Installer for Windows `_ +.. _build_source: + Build from Source ================= diff --git a/tutorials/tut0.rst b/tutorials/tut0.rst new file mode 100644 index 000000000..305095355 --- /dev/null +++ b/tutorials/tut0.rst @@ -0,0 +1,214 @@ +Tutorial 0 - Get it Running +=========================== + +Welcome to PostgREST! In this pre-tutorial we're going to get things running so you can create your first simple API. + +PostgREST is a standalone web server which turns a PostgreSQL database into a RESTful API. It serves an API that is customized based on the structure of the underlying database. + +.. image:: ../_static/tuts/tut0-request-flow.png + +To make an API we'll simply be building a database. All the endpoints and permissions come from database objects like tables, views, roles, and stored procedures. These tutorials will cover a number of common scenarios and how to model them in the database. + +By the end of this tutorial you'll have a working database, PostgREST server, and a simple single-user todo list API. + +Step 1. Relax, we'll help +------------------------- + +As you begin the tutorial, pop open the project `chat room `_ in another tab. There are a nice group of people active in the project and we'll help you out if you get stuck. + +Step 2. Install PostgreSQL +-------------------------- + +You'll need a modern copy of the database running on your system, either natively or in a Docker instance. We require PostgreSQL 9.3 or greater, but recommend at least 9.5 for row-level security features that we'll use in future tutorials. + +If you're already familiar with using PostgreSQL and have it installed on your system you can use the existing installation. For this tutorial we'll describe how to use the database in Docker because database configuration is otherwise too complicated for a simple tutorial. + +If Docker is not installed, you can get it `here `_. Next, let's pull and start the database image: + +.. code-block:: bash + + sudo docker run --name tutorial -p 5432:5432 \ + -e POSTGRES_PASSWORD=mysecretpassword \ + -d postgres + +This will run the Docker instance as a daemon and expose port 5432 to the host system so that it looks like an ordinary PostgreSQL server to the rest of the system. + +Step 3. Install PostgREST +------------------------- + +PostgREST is distributed as a single binary, with versions compiled for major distributions of Linux/BSD/Windows. Visit the `latest release `_ for a list of downloads. In the event that your platform is not among those already pre-built, see :ref:`build_source` for instructions how to build it yourself. Also let us know to add your platform in the next release. + +The pre-built binaries for download are :code:`.tar.xz` compressed files (except Windows which is a zip file). To extract the binary, go into the terminal and run + +.. code-block:: bash + + # download from https://github.com/begriffs/postgrest/releases/latest + + tar xfJ postgrest--.tar.xz + +The result will be a file named simply :code:`postgrest` (or :code:`postgrest.exe` on Windows). At this point try running it with + +.. code-block:: bash + + ./postgrest + +If everything is working correctly it will print out its version and information about configuration. You can continue to run this binary from where you downloaded it, or copy it to a system directory like :code:`/usr/local/bin` on Linux so that you will be able to run it from any directory. + +.. note:: + + PostgREST requires libpq, the PostgreSQL C library, to be installed on your system. Without the library you'll get an error like "error while loading shared libraries: libpq.so.5." Here's how to fix it: + + .. raw:: html + +

+

+ Ubuntu or Debian +
+
sudo apt-get install libpq-dev
+
+
+
+ Fedora, CentOS, or Red Hat +
+
sudo yum install postgresql-libs
+
+
+
+ OS X +
+
brew install postgresql
+
+
+
+ Windows +

It isn't fun. Learn more here.

+

It might be easier to execute PostgREST in its own Docker image as well.

+
+

+ +Step 4. Create Database for API +------------------------------- + +Connect to to SQL console (psql) inside the container. To do so, run this from your command line: + +.. code-block:: bash + + sudo docker exec -it tutorial psql -U postgres + +You should see the psql command prompt: + +:: + + psql (9.6.3) + Type "help" for help. + + postgres=# + +The first thing we'll do is create a `named schema `_ for the database objects which will be exposed in the API. We can choose any name we like, so how about "api." Execute this and the other SQL statements inside the psql prompt you started. + +.. code-block:: postgres + + create schema api; + +Our API will have one endpoint, :code:`/todos`, which will come from a table. + +.. code-block:: postgres + + create table api.todos ( + id serial primary key, + done boolean not null default false, + task text not null, + due timestamptz + ); + + insert into api.todos (task) values + ('finish tutorial 0'), ('pat self on back'); + +Next make a role to use for anonymous web requests. When a request comes in, PostgREST will switch into this role in the database to run queries. + +.. code-block:: postgres + + create role web_anon nologin; + grant web_anon to postgres; + + grant usage on schema api to web_anon; + grant select on api.todos to web_anon; + +The :code:`web_anon` role has permission to access things in the :code:`api` schema, and to read rows in the :code:`todos` table. + +Now quit out of psql; it's time to start the API! + +.. code-block:: psql + + \q + +Step 5. Run PostgREST +--------------------- + +PostgREST uses a configuration file to tell it how to connect to the database. Create a file :code:`tutorial.conf` with this inside: + +.. code-block:: ini + + db-uri = "postgres://postgres:mysecretpassword@localhost/postgres" + db-schema = "api" + db-anon-role = "web_anon" + +The configuration file has other :ref:`options `, but this is all we need. Now run the server: + +.. code-block:: bash + + ./postgrest tutorial.conf + +You should see + +.. code-block:: text + + Listening on port 3000 + Attempting to connect to the database... + Connection successful + +It's now ready to serve web requests. There are many nice graphical API exploration tools you can use, but for this tutorial we'll use :code:`curl` because it's likely to be installed on your system already. Open a new terminal (leaving the one open that PostgREST is running inside). Try doing an HTTP request for the todos. + +.. code-block:: bash + + curl http://localhost:3000/todos + +The API replies: + +.. code-block:: json + + [ + { + "id": 1, + "done": false, + "task": "finish tutorial 0", + "due": null + }, + { + "id": 2, + "done": false, + "task": "pat self on back", + "due": null + } + ] + +With the current role permissions, anonymous requests have read-only access to the :code:`todos` table. If we try to add a new todo we are not able. + +.. code-block:: bash + + curl http://localhost:3000/todos -X POST \ + -H "Content-Type: application/json" \ + -d '{"task": "do bad thing"}' + +Response is 401 Unauthorized: + +.. code-block:: json + + { + "hint": null, + "details": null, + "code": "42501", + "message": "permission denied for relation todos" + } + +There we have it, a basic API on top of the database! In the next tutorials we will see how to extend the example with more sophisticated user access controls, and more tables and queries.