CRUD URL Design for Browsers (not REST)
Asked Answered
S

1

11

Many questions has been asked on Stack Overflow for RESTful URL design

To name a few...

Hierarchical URL Design: Hierarchical RESTful URL design

Understanding REST: Verbs, error codes, and authentication: Understanding REST: Verbs, error codes, and authentication

So I am well aware for Restful URL Design. However, how about URL Design for the Browser for traditional Websites which are not Single Page Applications (SPA).

For the purpose of this example, lets assume we have a Book Database. Lets further assume we have 2 traditional HTML sites created.

  1. HTML Table for showing all books
  2. HTML Form for showing one book (blank or pre-filled with book details)

Now we want that the user of our website can do CRUD operations with it. How about the following URL Design then:

GET /book/show/all        // HTML Table
GET /book/show/{id}       // HTML Form pre-filled
GET /book/new             // HTML Form blank
POST /book/new            // Submit HTML Form
POST /book/update/{id}    // Submit updated HTML Form
POST /book/delete/{id}    // A Link/Button with POST ability (no JS needed)

Questions:

Best practise Browser URL Design

Am I following best practice for URL Design in the Browser (I am not talking about REST here)? Also regarding SEO, Bookmarking and short URL Design? I was thinking of something like: /resource/action/ ...

GET and POST only URL Design

Browsers can only make GET and POST unless someone uses JavaScript. Considering the above URL Design, should it be wiser to introduce JavaScript and make PUT and DELETE requests for updating and deleting a resource? Or should I stay with GET and POST only?

Cheers

Stairhead answered 23/4, 2017 at 7:52 Comment(0)
P
15

Instead of CRUD (create-read-update-delete), I prefer the acronym (D)AREL (display, add, remove, edit, list) -- the (D) is silent ;-)

While not all RESTful API design choices make sense for a browser based crud app, we can borrow much of it, e.g.:

GET  /books                -- html table listing all books (alternatively /books/list to go with the DAREL acronym)
GET  /books/add            -- display a form for adding a new book
POST /books/add            -- adds a new book and redirects to /book/1 (where 1 is a new book id)

I personally prefer to use plural nouns for collections and singular nouns for items, so..

GET  /book/1               -- display book 1 info (e.g. a customer view)
GET  /book/1/edit          -- display a form to edit /book/1
POST /book/1/edit          -- updates /book/1 and redirects to /book/1
GET  /book/1/remove        -- maybe/probably optional
POST /book/1/remove        -- normally /book/1/edit will have a delete button that handles "are you sure..?" and posts here, redirects to /books

The uri scheme is /resource/unique-identifier/action. The (D) / display action is silent/default for a given resource uri.

This also works if you want to model that a book can have multiple authors:

GET  /book/1/authors       -- list all authors for /book/1
GET  /book/1/authors/add   -- add author form
GET  /book/1/author/1
GET  /book/1/author/1/edit
// etc.

although you will likely need a separate/additional url-hierarchy for authors:

GET  /authors
GET  /authors/add
GET  /author/1
// etc.

and similarly, books that an author has written:

GET  /author/1/books
// etc.

Most modern web-apps use ajax calls for sub-resources though, so here you can use a pure RESTful api too:

GET    /api/book/1/authors     -- returns list of all authors for /book/1
POST   /api/book/1/authors     -- create a new author, returns the new author uri, e.g. /api/author/1
GET    /api/author/1           -- get /author/1 info according to MIME type etc.
PUT    /api/author/1           -- update /author/1
DELETE /api/author/1           -- delete the /author/1 resource
DELETE /api/book/1/author/1    -- delete author/1 from /book/1? (or maybe this is covered by PUT /api/author/1 ?)

The translation from the original url-scheme is pretty mechanical

/resource/unique-id/action -> http-verb /resource/unique-id

where action = http-verb

display = GET (on a singular resource)
add = POST
remove = DELETE
edit = PUT
list = GET (on a plural/collection resource)
Penetration answered 7/5, 2019 at 7:39 Comment(3)
I would use plural nouns for individual items, i.e. /books/1. That makes all segments of the path meaningful, makes traversing through the paths easier to navigate, and works more naturally for breadcrumbs etc.Bahadur
Suppose you had a strict hierarchy of states and counties, such that you never want to see all counties without specifying the parent state. Would you do that filtering via /state/123/counties, or /counties?stateId=123 or some other way?Orcus
@JoshuaFrank for listing them I would normally do /state/123/counties - while looking at a single county could be both /county/42 and /state/123/county/42 (or just the latter if the hierarchy was so important that counties without state specified didn't have any meaning.Penetration

© 2022 - 2024 — McMap. All rights reserved.