-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathkwebapp.xml
250 lines (249 loc) · 11.2 KB
/
kwebapp.xml
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
<!DOCTYPE html>
<html lang="en" prefix="og: http://ogp.me/ns#">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>BCHS//openradtool: rapid application development</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Alegreya+Sans:400,400italic,500" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
<link rel="stylesheet" href="highlight.css" />
<link rel="stylesheet" href="kwebapp.css" />
<link rel="shortcut icon" type="image/png" href="/favicon-196x196.png" />
<link rel="shortcut icon" sizes="196x196" href="/favicon-196x196.png" />
<link rel="apple-touch-icon" href="/favicon-196x196.png" />
<meta property="og:title" content="BCHS and openradtool: rapid application development" />
<meta property="og:image" content="https://learnbchs.org/logo-blue.png" />
<meta property="og:url" content="https://learnbchs.org/kwebapp.html" />
<meta property="og:type" content="website" />
<meta property="og:description" content="Introduction to using openradtool in your BCHS stack." />
<meta name="description" content="Introduction got using openradtool in your BCHS stack." />
</head>
<body>
<section itemscope="itemscope" itemtype="http://schema.org/WebPage">
<nav class="subnav">
openradtool series:
<a href="kwebapp.html">introduction</a>,
<a href="rbac.html">RBAC</a>,
<a href="auditing.html">role audits</a>,
<a href="translate.html">translation</a>,
<a href="typescript.html">TypeScript</a>
</nav>
<header>
<img itemprop="image" src="logo-blue.png" alt="BCHS Logo" />
<h1>
<a href="index.html" itemprop="name">BCHS</a>
</h1>
<nav>
<a href="tools.html"><span>tools</span></a>
<a href="easy.html"><span>example</span></a>
<a href="https://github.com/kristapsdz/bchs"><i class="fa fa-github"></i></a>
</nav>
</header>
<article>
<header>
<p class="intro">
One of the most rewarding parts of back-end web application development is re-writing the same
database routines and same JSON export routines over and over.
Then changing the requirements and starting over.
It's what makes web application developers such well-balanced folks, right?
</p>
<p>
Unfortunately, in the flux of user requirements—each addition or modification of
a table column changing select routines, insertions, validation, exporting, regression tests,
and even (especially?) front-end JavaScript—we make mistakes.
What <a href="index.html">BCHS</a> tools beyond the <a href="tools.html">usual</a> can help in
this perennial test of our patience?
</p>
<h2>
<span>ort(1)</span>
</h2>
</header>
<section>
<p>
I wrote <a href="https://kristaps.bsd.lv/openradtool">openradtool</a> after the <del>tenth</del>
hundredth time I started a new <a href="index.html">BCHS</a> web application roughly as follows:
</p>
<ol>
<li>
design an initial table schema (<q>data layout</q>) from a specification;
</li>
<li>
pull down <a href="https://github.com/kristapsdz/kcgi-framework">kcgi-framework</a> as a
starting point;
</li>
<li>
create a set of C structures mirroring the data layout (e.g., kcgi-framework's <a
href="https://github.com/kristapsdz/kcgi-framework/blob/master/extern.h">extern.h</a>);
</li>
<li>
grind on <code>INSERT</code>, <code>UPDATE</code>, <code>SELECT</code> and
<code>DELETE</code> routines using the same tired way of chaining together column
schemas with <q>fill</q> and <q>unfill</q> routines (e.g., <a
href="https://github.com/kristapsdz/kcgi-framework/blob/master/db.c">db.c</a>)
connected to the C API;
</li>
<li>
construct the application logic (e.g., <a
href="https://github.com/kristapsdz/kcgi-framework/blob/master/main.c">main.c</a>
connecting these components and driving my application; and finally
</li>
<li>
make typo mistakes in SQL, have inconsistent documentation between the SQL and C API,
forget parameters, incorrectly validate, and so on—problems that only arise in
actually testing the individual parts or having a colleague scratch her head over
mismatches.
</li>
</ol>
<p>
All of this takes time, which is something in high demand; and my colleagues' patience, which is
even more scarce.
In case we forget where the <em>real</em> work's at, what happens in the commonplace event that
our specification changes during the review phase?
</p>
<figure>
<img src="kwebapp-fig1.svg" alt="" />
<figure>
The circle of <del>life</del> work.
</figure>
</figure>
<ol>
<li>
Add an additional column to (or modify an existing column of) a database table;
</li>
<li>
create an additional SQL <q>upgrade</q> script between the last version and the current
version (of course, you're using <a href="https://man.openbsd.org/cvs">cvs(1)</a>'s
tagging facility or other VCS to track your production and development releases);
</li>
<li>
update the C structures, column definitions, fill and unfill routines (naturally,
forgetting to update the documentation);
</li>
<li>
change the <q>business logic</q> accepting the new field, validating it, and passing it
back into the database backend and JSON export; then
</li>
<li>
change the front-end code (JavaScript, HTML5) to include the new value.
</li>
</ol>
<p>
Folks programming in Java or Python have all sorts of fancy tools and frameworks to help them
suck data out and send it to the client.
(I guess.)
When I'm writing in C, I don't.
<a href="https://kristaps.bsd.lv/openradtool">openradtool</a> was a way to automate a lot of the steps
above into a single one when using my tools: <a href="https://kristaps.bsd.lv/kcgi">kcgi</a>, <a
href="https://kristaps.bsd.lv/ksql">ksql</a> (that is, <a
href="https://sqlite.org">SQLite</a>), and of course <a
href="https://www.openbsd.org">OpenBSD</a>.
</p>
<p>
Read this and see if it makes sense:
</p>
<article data-sblg-article="1" data-sblg-permlink="0"></article>
<p>
Hopefully it does.
We have two objects: a <code>user</code> and a user's <code>session</code>.
As C programmers, you're interpreting them as <code>struct</code>s;
or if you're more SQL-minded, as tables.
Both are correct.
Moreover, the snippet defines not only the relationship between two objects as might envision in
an SQL database, but also limitations on input data (the <code>limit</code> clause) and
documentation (the <code>comment</code> clause).
It also specifies some terms to search on, e.g., <code>email</code> and <code>hash</code> for
users—passwords are automatically hashed using the
<a href="https://man.openbsd.org/crypt_checkpass">crypt_checkpass(3)</a> family.
</p>
<p>
When run through <a href="https://kristaps.bsd.lv/openradtool">openradtool</a>, it automates the
production of many of the elements in our above graph:
</p>
<ul>
<li>
SQL: the <a href="kwebapp.db.sql.html">SQL schema</a> required by the data definitions;
</li>
<li>
C API: not only the <a href="kwebapp.db.h.html">header</a> (structures, functions), but
the full <a href="kwebapp.db.c.html">implementation</a> acting upon the SQL definitions;
</li>
<li>
REST API: a set of functions for exporting the C API into JSON (included in the C API <a
href="kwebapp.db.h.html">header</a> and <a
href="kwebapp.db.c.html">implementation</a>); and
</li>
<li>
JavaScript: a <a href="kwebapp.db.js.html">set of objects</a> for filling in DOM trees
with the defined data.
</li>
</ul>
<figure>
<img src="kwebapp-fig2.svg" alt="" />
<figure>
The simplified process.
</figure>
</figure>
<p>
The SQL is managed by <a href="https://kristaps.bsd.lv/openradtool">openradtool</a>—not just
generatively, but within the update cycle.
It's able to generate the <a href="kwebapp.db.sqldiff.html">difference</a> between
configurations (in this example, one without the foreign key on the session)—allowing you
to see how your database has changed between versions.
This is particularly useful when rolling out incremental releases.
(Of course, not all data layout changes can be realised with SQLite's SQL!)
</p>
<p>
You'll still need to update your front-end logic, of course, to reflect your new data.
And your application logic—obviously.
But the rest of the tedious cycle—C API, validators, JSON exporters, etc.—are all
handled by <a href="https://kristaps.bsd.lv/openradtool">openradtool</a>.
</p>
<p>
For an example of how a backend might look, consider <a href="kwebapp.main.c.html">main.c</a>.
This handles logging in, logging out, and a simple homepage using the given example.
Take, for example, the component where it processes a request's cookies using the <span
class="nm">openradtool</span> functions for reading from the database:
</p>
<article data-sblg-article="1" data-sblg-permlink="0"></article>
<p>
Upon login, it uses the <span class="nm">openradtool</span>-generated output functions to emit JSON:
</p>
<article data-sblg-article="1" data-sblg-permlink="0"></article>
<p>
All of the <a href="https://kristaps.bsd.lv/kcgi">kcgi(3)</a> functions are fully documented,
and the generated functions are also documented in <a href="kwebapp.db.h.html">kwebapp.db.h</a>.
Much easier!
</p>
<h3>
where is openradtool going
</h3>
<p>
Short answer: wherever we want.
Longer answer? Most of my immediate intentions are in the <a
href="https://github.com/kristapsdz/openradtool/blob/master/TODO.md">TODO</a>.
</p>
<p>
What will I not do myself in the near-term?
Expand to other databases, namely <a
href="https://www.postgresql.org/">PostgreSQL</a>—though that's really a job for
<a href="https://kristaps.bsd.lv/ksql">ksql</a>.
(I think <a href="https://kristaps.bsd.lv/ksql">ksql</a> is due for some care on having a
privilege-separated model of operation for easier <a href="https://man.openbsd.org/pledge.2">pledging</a>.)
I'd also like it to document the JSON export, for example, with <a
href="http://json-schema.org/">JSON Schema</a>.
</p>
<p>
Meanwhile, if you're using <a href="https://kristaps.bsd.lv/openradtool">openradtool</a> for any
projects, keep me in the loop!
</p>
</section>
</article>
<footer>
<div>
<a href="https://creativecommons.org/licenses/by/4.0/"><i class="fa fa-creative-commons"></i></a>
<a rel="author" href="https://kristaps.bsd.lv">Kristaps Dzonsons</a>
</div>
</footer>
</section>
</body>
</html>