~bigbes/tarantool

tarantool-protobuf

ref: 6e7835a29a3678aa86a49dfff76c55b18d091755 tarantool-protobuf/examples/http/json_api.lua -rw-r--r-- 2.0 KiB
6e7835a2 — Eugene Blikh c_runtime: encode/decode singular sub-messages (ra6 3d) 2 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
-- JSON-over-HTTP server example using tarantool/http.
--
-- Pattern:
--   POST /v1/users
--     Content-Type: application/json
--     Body:        proto3 JSON for hello.Person
--   Response:
--     200 OK
--     Content-Type: application/json
--     Body:        same shape, plus the generated user_id
--
-- Run with:
--   LUA_PATH="./runtime/?/init.lua;./runtime/?.lua;./examples/expected/?.lua;./examples/expected/?/init.lua;;" \
--     tarantool examples/http/json_api.lua
--
-- Then:
--   curl -X POST http://127.0.0.1:8080/v1/users \
--        -H 'Content-Type: application/json' \
--        -d '{"name":"Alice","age":30,"emails":["a@x"]}'

local pb = require('pb')
local hello = require('full.hello.hello_pb')

-- tarantool-http is installed via `tt rocks install http`; without it,
-- swap in your project's preferred HTTP framework.
local httpd_ok, http = pcall(require, 'http.server')
if not httpd_ok then
    error('this example needs the `http.server` rock: tt rocks install http')
end

local httpd = http.new('127.0.0.1', 8080)

httpd:route({path = '/v1/users', method = 'POST'}, function(req)
    -- Parse the request body as proto3 JSON.
    local body = req:read_cached()
    local ok, person = pcall(pb.json.decode, hello.Person_descriptor, body, {
        -- Accept (and ignore) keys the schema doesn't know — handy for
        -- forward-compat clients that send extras.
        ignore_unknown_fields = true,
    })
    if not ok then
        return {status = 400, headers = {['content-type'] = 'application/json'},
                body = pb.json.encode(hello.HelloReply_descriptor,
                                      {greeting = 'bad request: ' .. person})}
    end

    -- (Pretend) business logic: assign a user_id.
    person.user_id = pb.to_uint64(42)

    return {
        status = 200,
        headers = {['content-type'] = 'application/json'},
        body = pb.json.encode(hello.Person_descriptor, person),
    }
end)

httpd:start()
print('listening on http://127.0.0.1:8080')
require('fiber').sleep(math.huge)  -- block; Ctrl-C to stop