Skip to content
This repository was archived by the owner on Feb 24, 2024. It is now read-only.

Commit 7d0588a

Browse files
committed
reference: media type handlers
1 parent e620ae5 commit 7d0588a

10 files changed

+303
-161
lines changed

docs/how-tos/create-soap-endpoint.rst

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,20 @@ Create a SOAP endpoint
55

66
:author: `fjf2002 <https://github.com/fjf2002>`_
77

8-
PostgREST now has XML support. With a bit of work, SOAP endpoints become possible.
9-
10-
Please note that PostgREST supports just ``text/xml`` MIME type in request/response headers ``Content-Type`` and ``Accept``.
11-
If you have to use other MIME types such as ``application/soap+xml``, you could manipulate the headers in your reverse proxy.
12-
13-
8+
PostgREST supports :ref:`custom_media`. With a bit of work, SOAP endpoints become possible.
149

1510
Minimal Example
1611
---------------
12+
1713
This example will simply return the request body, inside a tag ``therequestbodywas``.
1814

1915
Add the following function to your PostgreSQL database:
2016

2117
.. code-block:: postgres
2218
23-
CREATE OR REPLACE FUNCTION my_soap_endpoint(xml) RETURNS xml AS $$
19+
create domain "text/xml" as pg_catalog.xml;
20+
21+
CREATE OR REPLACE FUNCTION my_soap_endpoint(xml) RETURNS "text/xml" AS $$
2422
DECLARE
2523
nsarray CONSTANT text[][] := ARRAY[
2624
ARRAY['soapenv', 'http://schemas.xmlsoap.org/soap/envelope/']
@@ -121,7 +119,7 @@ potentially disclosing internals to the client, but instead handle the errors di
121119
xmlelement(NAME "soapenv:Body", body)
122120
);
123121
$function$;
124-
122+
125123
-- helper function
126124
CREATE OR REPLACE FUNCTION _soap_exception(
127125
faultcode text,
@@ -137,9 +135,9 @@ potentially disclosing internals to the client, but instead handle the errors di
137135
)
138136
);
139137
$function$;
140-
138+
141139
CREATE OR REPLACE FUNCTION fraction_to_decimal(xml)
142-
RETURNS xml
140+
RETURNS "text/xml"
143141
LANGUAGE plpgsql
144142
AS $function$
145143
DECLARE
@@ -207,14 +205,14 @@ The output should roughly look like:
207205
</soapenv:Body>
208206
</soapenv:Envelope>
209207
210-
211208
References
212209
----------
210+
213211
For more information concerning PostgREST, cf.
214212
215213
- :ref:`s_proc_single_unnamed`
216-
- :ref:`scalar_return_formats`
217-
- :ref:`Nginx reverse proxy <admin>`
214+
- :ref:`custom_media`. See :ref:`any_handler`, if you need to support an ``application/soap+xml`` media type.
215+
- :ref:`Nginx reverse proxy <nginx>`
218216
219217
For SOAP reference, visit
220218

docs/how-tos/providing-images-for-img.rst

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,42 @@ First, we need a public table for storing the files.
2626
, blob bytea
2727
);
2828
29-
Let's assume this table contains an image of two cute kittens with id 42.
30-
We can retrieve this image in binary format from our PostgREST API by requesting :code:`/files?select=blob&id=eq.42` with the :code:`Accept: application/octet-stream` header.
31-
Unfortunately, putting the URL into the :code:`src` of an :code:`<img>` tag will not work.
32-
That's because browsers do not send the required :code:`Accept: application/octet-stream` header.
29+
Let's assume this table contains an image of two cute kittens with id 42. We can retrieve this image in binary format from our PostgREST API by using :ref:`custom_media`:
30+
31+
.. code-block:: postgres
32+
33+
create domain "application/octet-stream" as bytea;
34+
35+
create or replace function file(id int) returns "application/octet-stream" as $$
36+
select blob from files where id = file.id;
37+
$$ language sql;
38+
39+
Now we can request the RPC endpoint :code:`/rpc/file?id=42` with the :code:`Accept: application/octet-stream` header.
40+
41+
42+
.. code-block:: bash
43+
44+
curl "localhost:3000/rpc/file?id=42" -H "Accept: application/octet-stream"
45+
46+
47+
Unfortunately, putting the URL into the :code:`src` of an :code:`<img>` tag will not work. That's because browsers do not send the required :code:`Accept: application/octet-stream` header.
48+
Instead, the :code:`Accept: image/webp` header is sent by many web browsers by default.
49+
50+
Luckily we can change the accepted media type in the function like so:
51+
52+
.. code-block:: postgres
53+
54+
create domain "image/webp" as bytea;
55+
56+
create or replace function file(id int) returns "image/webp" as $$
57+
select blob from files where id = file.id;
58+
$$ language sql;
3359
34-
Luckily we can specify the accepted media types in the :ref:`raw-media-types` configuration variable.
35-
In this case, the :code:`Accept: image/webp` header is sent by many web browsers by default, so let's add it to the configuration variable, like this: :code:`raw-media-types="image/webp"`.
3660
Now, the image will be displayed in the HTML page:
3761

3862
.. code-block:: html
3963

40-
<img src="http://localhost:3000/files?select=blob&id=eq.42" alt="Cute Kittens"/>
64+
<img src="http://localhost:3000/file?id=42" alt="Cute Kittens"/>
4165

4266
Improved Version
4367
----------------
@@ -60,13 +84,15 @@ First, in addition to the minimal example, we need to store the media types and
6084
add column type text,
6185
add column name text;
6286
63-
Next, we set up an RPC endpoint that sets the content type and filename.
87+
Next, we set modify the function to set the content type and filename.
6488
We use this opportunity to configure some basic, client-side caching.
6589
For production, you probably want to configure additional caches, e.g. on the :ref:`reverse proxy <admin>`.
6690

6791
.. code-block:: postgres
6892
69-
create function file(id int) returns bytea as
93+
create domain "*/*" as bytea;
94+
95+
create function file(id int) returns "*/*" as
7096
$$
7197
declare headers text;
7298
declare blob bytea;
@@ -79,7 +105,7 @@ For production, you probably want to configure additional caches, e.g. on the :r
79105
from files where files.id = file.id into headers;
80106
perform set_config('response.headers', headers, true);
81107
select files.blob from files where files.id = file.id into blob;
82-
if found
108+
if FOUND -- special var, see https://www.postgresql.org/docs/current/plpgsql-statements.html#PLPGSQL-STATEMENTS-DIAGNOSTICS
83109
then return(blob);
84110
else raise sqlstate 'PT404' using
85111
message = 'NOT FOUND',

docs/how-tos/working-with-postgresql-data-types.rst

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -506,33 +506,26 @@ Now, to send the file ``postgrest-logo.png`` we need to set the ``Content-Type:
506506
-X POST -H "Content-Type: application/octet-stream" \
507507
--data-binary "@postgrest-logo.png"
508508

509-
To get the image from the database, set the ``Accept: application/octet-stream`` header and select only the
510-
``bytea`` type column.
509+
To get the image from the database, use :ref:`custom_media` like so:
511510

512-
.. tabs::
513-
514-
.. code-tab:: http
515-
516-
GET /files?select=file&id=eq.1 HTTP/1.1
517-
Accept: application/octet-stream
518-
519-
.. code-tab:: bash Curl
511+
.. code-block:: postgres
520512
521-
curl "http://localhost:3000/files?select=file&id=eq.1" \
522-
-H "Accept: application/octet-stream"
513+
create domain "image/png" as bytea;
523514
524-
Use more accurate headers according to the type of the files by using the :ref:`raw-media-types` configuration. For example, adding the ``raw-media-types="image/png"`` setting to the configuration file will allow you to use the ``Accept: image/png`` header:
515+
create or replace get_image(id int) returns "image/png" as $$
516+
select file from files where id = $1;
517+
$$ language sql;
525518
526519
.. tabs::
527520

528521
.. code-tab:: http
529522

530-
GET /files?select=file&id=eq.1 HTTP/1.1
523+
GET /get_image?id=1 HTTP/1.1
531524
Accept: image/png
532525

533526
.. code-tab:: bash Curl
534527

535-
curl "http://localhost:3000/files?select=file&id=eq.1" \
528+
curl "http://localhost:3000/get_image?id=1" \
536529
-H "Accept: image/png"
537530

538531
See :ref:`providing_img` for a step-by-step example on how to handle images in HTML.

0 commit comments

Comments
 (0)