~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to doc/webapp-process.txt

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2004-07-07 14:14:22 UTC
  • Revision ID: Arch-1:rocketfuel@canonical.com%soyuz--devel--0--patch-22
correct broken commit that bypassessed arch-inventory

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
=========================================
 
2
How to go about writing a web application
 
3
=========================================
 
4
 
 
5
-- Steve Alexander <steve@z3u.com>
 
6
 
 
7
 
 
8
Introduction
 
9
------------
 
10
 
 
11
This document presents an approach to constructing web applications,
 
12
emphasising well-designed user interaction.
 
13
 
 
14
In summary, we write a web application by
 
15
 
 
16
1. Design the database that lies behind the web application
 
17
   - Entity relationship models
 
18
   - SQL statements
 
19
2. Design the web application's user interface
 
20
   - Table of URLs (see later)
 
21
   - Page tempate mock-ups
 
22
3. Write the Interfaces that the application will use to access the database
 
23
   - interfaces.py files
 
24
4. Write the code and templates of the application
 
25
   - page templates
 
26
   - supporting classes
 
27
   - application components
 
28
 
 
29
Of course, this isn't a completely linear process.  Steps may be carried out
 
30
in parallel, and ongoing work in each step will feed into the other steps.
 
31
 
 
32
So that we can make rapid progress, and learn about the application as early
 
33
as possible, we should do steps 2, 3 and 4 focusing on just a few URLs at
 
34
a time (say, five or so).  Then, when those are finished, we can make any
 
35
necessary changes to the database model, and then repeat steps 2, 3 and 4
 
36
with some new URLs and new application functionality.
 
37
 
 
38
 
 
39
 
 
40
Web application architecture
 
41
----------------------------
 
42
 
 
43
For the purposes of this document, a web application is put together as
 
44
follows::
 
45
 
 
46
 +--------------------------------------------------------------------------+
 
47
 |              {  Amorphous cloud of URLs  }                               |
 
48
 |  URLS      {   /rosetta/foo/bar/baz.html   }                             |
 
49
 |             {                             }                              |
 
50
 |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  |
 
51
 |                           { Pages       SubURLs                          |
 
52
 |            PRESENTATION   { Views       Templates                        |
 
53
 |                           { Traversal   Support classes                  |
 
54
 |                                                                          |
 
55
 |  WEB APP   ------------------------------------------------- Interfaces  |
 
56
 |                                                                          |
 
57
 |            APPLICATION    { Utilities   Components                       |
 
58
 |            COMPONENTS     { Adapters                                     |
 
59
 |                                                                          |
 
60
 |                                                                          |
 
61
 |            LIBRARIES      { Python standard library                      |
 
62
 |                           { Other libraries                              |
 
63
 |                                                                          |
 
64
 |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   |
 
65
 |                                                                          |
 
66
 |  DATABASE     relations, fields, constraints                             |
 
67
 +--------------------------------------------------------------------------+
 
68
 
 
69
The boundaries of our web application are URLs at the top and the database
 
70
at the bottom.  So, we must carefully define these things that lie at the
 
71
boundaries, so that we can work out what must go in the middle.
 
72
 
 
73
URLs
 
74
----
 
75
 
 
76
URLs are the boundary between the web application and web browsers.  When you
 
77
point a web browser at a URL, you'll get one of the following:
 
78
 
 
79
- page
 
80
- form
 
81
- image or other data
 
82
- redirect
 
83
- "not found" error
 
84
- "unauthorized" error
 
85
 
 
86
We'll be mostly concerned with pages, forms and redirects.  We'll be concerned
 
87
with image and other data only when they are "managed content" and not just
 
88
part of the skin of the site.  The photograph of a member of the site is an
 
89
example of managed content: it is stored in the database and may be
 
90
manipulated through using the application.  CSS files, javascript files,
 
91
icons and logos are typically elements that make up the "skin" of the
 
92
application, and are not managed through the application.
 
93
 
 
94
Another example of image or other data that is managed content is if we want
 
95
to allow users to download a .po or .pot file of translations.
 
96
 
 
97
Forms are rendered in HTML and will typically be "self-posting forms".  That
 
98
is, the address posted to when the [submit] button is pressed will be the
 
99
same as the address the page was got from.  This allows browsers' bookmarks
 
100
to work properly, allows us to straightforwardly validate data entered into
 
101
the form, and keeps the URL space neat.
 
102
 
 
103
The "not found" error is the familiar "404 Not Found" given when someone
 
104
tries to access a URL that is not known by our system.
 
105
 
 
106
An "unauthorized" error means that accessing the given URL requires some
 
107
authentication.  The browser will prompt the user to provide some additional
 
108
authentication.  Alternatively, if we use other login schemes than HTTP Basic
 
109
or HTTP Digest, then the web application may present a login form to the
 
110
user.
 
111
 
 
112
A "redirect" causes the browser to immediately fetch a different URL.  This
 
113
process is usually not noticed by the user.
 
114
 
 
115
 
 
116
The URL table
 
117
-------------
 
118
 
 
119
We need to construct a table describing the URLs used in our application. We
 
120
won't bother about the protocol part or any leading path segments of the URL.
 
121
In the table below, we'll assume all URLs start http://example.com/rosetta/...
 
122
 
 
123
The table has the following columns
 
124
 
 
125
- URL: The rest of the URL after /rosetta.  For clarity, we'll start it with
 
126
  a "./".  So, the rosetta application's main page might be "./index.html".
 
127
  If this table is written in HTML, this may be a link to a mock-up HTML page
 
128
  showing what will be found at that URL.
 
129
 
 
130
- Default: For application components, the default page to use.  More about
 
131
  this later.
 
132
 
 
133
- Type: This is one of "app component", "page", "form", "redirect", "data"
 
134
 
 
135
- Description: A textual description of what is found at this URL.
 
136
  This may be a link to further information about the functioning of that
 
137
  page, form validation constraints, and so on.
 
138
 
 
139
When you get an App Component at a particular URL, what does that mean?  At
 
140
certain points in our URL space, we want to expose a set of related
 
141
functionality under a particular URL.  For example, the URL
 
142
"./projects/mozilla/show-teams" might show the teams working on the Mozilla
 
143
project, while "./projects/mozilla/translations" might show the translations
 
144
of the mozilla project.  Users of the system will come to understand that
 
145
things related to Mozilla are to be found at URLs starting with
 
146
"./projects/mozilla".  We want to present some page at "./projects/mozilla".
 
147
Rather than make a special "no name" page for this, we choose one of the
 
148
other pages that we want to return.  Mozilla is a Project.  So, if the
 
149
default page for a Project is "translations", then going to
 
150
"./projects/mozilla" will return the same page as
 
151
"./projects/mozilla/translations".  The usual default page is "index.html".
 
152
 
 
153
 
 
154
Here's an example of a table for the Rosetta project::
 
155
 
 
156
  URL                 Default      Type            Description
 
157
 
 
158
  ./                  index.html   app component   The rosetta application
 
159
 
 
160
  ./index.html                     page            Initial navigation page
 
161
 
 
162
  ./intro.html                     page            Introductory page
 
163
 
 
164
  ./signup.html                    form            Allows a new user to
 
165
                                                   register with the system.
 
166
 
 
167
  ./projects          index.html   app component   Collection of rosetta
 
168
                                                   projects
 
169
 
 
170
  ./projects/index.html            form            Shows ways to search
 
171
                                                   through projects
 
172
 
 
173
  ./projects/$PROJECT translations app component   A particular project
 
174
                                                   $PROJECT is the name of
 
175
                                                   the project. See key below.
 
176
 
 
177
  ./projects/$PROJECT/translations page            Shows all translations
 
178
                                                   for this project.
 
179
 
 
180
 
 
181
  Key to $VARs
 
182
  ============
 
183
  $PROJECT    The name of the project.  This is the name attribute of
 
184
              the IProject interface, or the name field in the Project
 
185
              relation.  Case is not significant, and is normalized to
 
186
              lower-case in the UI.  Examples: 'mozilla', 'gtk+'.
 
187
 
 
188
We can use the URL table for simple automated functional testing of the web
 
189
application, given some suitable $VAR substitutions.
 
190
 
 
191
 
 
192
Structure of a web application URL
 
193
----------------------------------
 
194
 
 
195
We need to know what types of things are at a particular URL.  Here's an
 
196
example of a typical URL in a web application.  This time, I've included
 
197
the "rosetta" path segment at the root.
 
198
 
 
199
  /rosetta/projects/$PACKAGENAME/teams/$TEAM/add-member.html
 
200
   |       |        |            |     |     |
 
201
   |       |        |            |     |     page to add a new member
 
202
   |       |        |            |     Name of a particular team "22"
 
203
   |       |        |            The teams working on this project
 
204
   |       |        A particular project name, such as "mozilla"
 
205
   |       Collection of projects that can be queried
 
206
  The rosetta application
 
207
 
 
208
 
 
209
Guidelines for URLs
 
210
-------------------
 
211
 
 
212
* Make your URLs from lower-case letters, numbers, '-' and '+'.
 
213
 
 
214
* Avoid '_', capital letters, other symbols.
 
215
  Using these things makes the URL harder to read out over the phone or
 
216
  write down unambiguously.
 
217
 
 
218
* When you have a collection of things, such as people or projects, use
 
219
  a plural noun for that part of the URL.  For example, "./projects".
 
220
 
 
221
* Consider using "+" as the last URL segment for the URL that adds things
 
222
  to a collection.  For example, "./projects/+" to add a new project.
 
223
 
 
224
* Where possible, use self-posting forms.  So, you would go to the URL
 
225
  "./projects/+" to get a form asking you for the information needed to
 
226
  add a new project.  When you submit the form, it POSTs to the same
 
227
  URL.  If the provided informaiton is invalid, you'll get the form back
 
228
  with an error message.  Otherwise, you'll get a "success" message, or be
 
229
  redirected to the next page in the workflow.
 
230
 
 
231
 
 
232
 
 
233
Development iterations
 
234
----------------------
 
235
 
 
236
When you're developing a new system, don't try to write the whole table of
 
237
URLs at once.  Instead, we can work in iterative cycles, designing pages
 
238
and URLs, and making these work in software.  That way, we can learn earlier
 
239
on if the URLs and pages we want will actually work in practice.
 
240
 
 
241
Here's the overall process of developing the application.
 
242
 
 
243
Overall Process
 
244
~~~~~~~~~~~~~~~
 
245
 
 
246
1. Lay out the total functionality of the system, and divide it into a number
 
247
   of iterations.
 
248
2. Pick the next iteration.  Go through the Iteration Process described below.
 
249
3. Review / refactor the specification for previous iterations based on what
 
250
   we learned during this iteration.
 
251
4. Refactor the whole application implemented so far to match the refactored
 
252
   specification.
 
253
 
 
254
Each iteration (that is, step 2 above) looks like this.
 
255
 
 
256
Iteration Process
 
257
~~~~~~~~~~~~~~~~~
 
258
 
 
259
1. Write the URLs required for this iteration into the URLs table.
 
260
   Ideally, there should be 3 to 7 URLs in each iteration.
 
261
2. Document the functionality required for each page.
 
262
3. Produce page template mockups.
 
263
4. Implement the functionality, using stub application components rather
 
264
   than real application components.
 
265
5. Connect the functionality to the real database, by replacing the stubs
 
266
   with real application components.
 
267
 
 
268
 
 
269
I will note that these processes are just guidelines on how to go about writing
 
270
the software.  You might choose to prototype the application in order to learn
 
271
about what URLs are required for some tricky interaction. Or, you might decide
 
272
to write two iterations' worth of URLs into the URLs table all at once, but
 
273
then implement them in two iterations.  The important thing is to understand
 
274
where you are in this process, and why you are doing what you are doing at any
 
275
particular stage.
 
276
 
 
277
Keep the iterations short!
 
278
 
 
279
 
 
280
Glossary
 
281
--------
 
282
 
 
283
Skin:
 
284
    The way the user interface looks in a web browser.  The elements of this
 
285
    user interface, including CSS, images and an overall site template.
 
286
 
 
287
    It is possible to provide multiple skins to the same web application,
 
288
    for example a simple one and a very complex one.
 
289
 
 
290
Published:
 
291
    Something that is made available at a particular URL is said to be
 
292
    published.
 
293
 
 
294
Presentation component:
 
295
    Some software that interacts with the browser's request and returns
 
296
    information to the browser.  This is typically a page template or a
 
297
    page template plus a supporting class.
 
298
 
 
299
    Other presentation components are traversers, which know what to do
 
300
    when further path segments are given in a URL; and resources, which
 
301
    are CSS files, javascript files, logos, icons, etc.
 
302
 
 
303
Application component:
 
304
    An object that represents application functionality, but not presentation
 
305
    functionality.  It should have a well-defined interface so that different
 
306
    implementations of a given application component can be presented by
 
307
    the same presentation components.
 
308
 
 
309
Component:
 
310
    An object that has clearly defined interfaces.
 
311
 
 
312
    These interfaces may represent what it offers, or what it requires in
 
313
    order to function.
 
314
 
 
315
Utility:
 
316
    A component that is looked up by the interface that it provides.
 
317
 
 
318
Adapter:
 
319
    A component that knows how to use a particular interface in order to
 
320
    provide a different interface.
 
321
 
 
322
Interface:
 
323
    A software-readable definition of an API provided by some object.
 
324
 
 
325
View:
 
326
    A kind of presentation component that provides a representation of
 
327
    some other component.
 
328
 
 
329
Browser presentation:
 
330
    Presentation intended for a web browser, as distinct from a presentation
 
331
    intended for XML-RPC or webdav.  Or even email.
 
332
 
 
333
Non-published {view,resource}:
 
334
    A {view,resource} that is used by other presentation components, but
 
335
    that is not itself addressable by a URL.
 
336
 
 
337
Page:
 
338
    An HTML document returned to a browser in response to a GET or POST
 
339
    request to some URL.
 
340
 
 
341
Form:
 
342
    A page that contains HTML form elements and at least one "submit"
 
343
    button.
 
344
 
 
345
Self-posting form:
 
346
    A form that's "action URL" is the same address that it was loaded from.
 
347
    So, a form that was loaded from "./projects/+" would start::
 
348
 
 
349
      <form action="http://example.com/rosetta/projects/+" method="POST">
 
350
 
 
351
 
 
352
# arch-tag: cf2cb34d-52a5-4615-b135-439d70f43f36