I'm designing a set of RESTful API for a concept like "jobs". The model of a job looks like this:
Job: {
id: 1,
name: "Brew coffee",
status: "paused" | "running" | "finished",
progress: 0.75
}
and following RESTful principles, the client CRUDs jobs via HTTP verbs on /api/jobs. For example, initalizing a new job is
POST /api/jobs
--------------
Request body: {
name: "Push button"
}
---------------
Response status: 200 OK
Response body: {
id: 2,
name: "Cook dinner",
status: "running",
progress: 0
}
and accessing this job is
GET /api/jobs/2
--------------
Request body: {}
---------------
Response status: 200 OK
Response body: {
id: 2,
name: "Cook dinner",
status: "running",
progress: 0.5
}
My question is, how should I design the API for an action like "pause"? Off the top my head I'm consider between two
options:
One option is to design it as a PATCH request, and declare directly the end state I want, like so
PATCH /api/jobs/2
--------------
Request body: {
status: "paused"
}
---------------
Response status: 200 OK
Response body: {
id: 2,
name: "Cook dinner",
status: "paused",
progress: 0.65
}
The other option is to design it as a POST request, and declare the action I want, like so
POST /api/jobs/2
--------------
Request body: {
action: "pause"
}
---------------
Response status: 200 OK
Response body: {
// same as above
}
considering in the future I might implement other operations like "resume", "prioritize", "deprioritize", etc., which of these two options do you think is better? Or is there a even better practice?
My question is, how should I design the API for an action like "pause"?
How would you design a website to support an action like "pause"?
You'd probably start with a landing page, that the client could GET. The response you return would probably have a representation of the current state of the job, and would also have links, with semantic annotations that the user would understand. One of these would be for the "pause" action.
Following the pause link might GET a form, with a number of input fields, semantic annotations for each and probably default values for each field. The client would replace some or all of the values in the input fields, and submit the form.
That would POST the form data to the endpoint you specify, at which point your implementation would go about invoking the pause side effect, responding with a representation describing the result.
That's the model to follow. The implementation of your REST-API is an adapter that makes your service appear to be a generic website.
The key idea here is that the client doesn't need to know in advance the URI to use, or the http method to use, because that information is encoded into the representations of the links provided by the server. The client just needs to recognize and follow the links.
POST is fine; HTML clients have been using it since HTTP/1.0. PUT and PATCH are also fine, if you want to provide a "remote authoring" interface.
You may want to review Rest Causistry. Make sure that you go through the comments, which is where the real discussion of REST takes place. It's also useful to review Fielding's Paper Tigers and Hidden Dragons...
I should also note that the above is not yet fully RESTful, at least how I use the term. All I have done is described the service interfaces, which is no more than any RPC. In order to make it RESTful, I would need to add hypertext to introduce and define the service, describe how to perform the mapping using forms and/or link templates, and provide code to combine the visualizations in useful ways.
Matt Timmermans' comment has it right; if you are just documenting a bunch of disconnected endpoints that the client navigates on their own, then you aren't doing REST. And in solutions where you don't need to allow the clients and servers to evolve independently, that's also fine.
REST is intended for long-lived network-based applications that span multiple organizations. If you don’t see a need for the constraints, then don’t use them.
Following up to the comment:
it seems that this type of navigation-based API organization is very flexible if we are talking about a human operated client (like browser), but I'm not so sure it is easy to code an automatic client that can adjust changes in the server side. "... add hypertext to introduce and define the service, describe how to perform the mapping using forms and/or link templates ..." sounds all too human-oriented to me.
I had trouble with this too.
Nobody is claiming that, with a REST API, the machine consumers will magically be able to understand semantic changes in the API. If we want to support existing clients, then the changes we make on the server have to be done in a backwards compatible way. BUT - and this is the key idea - there's an extra layer of indirection between the semantics and the representation.
To choose a simple example, in an API with pagination, the consumer needs to understand the semantics of next page; it needs to be able to ask the client for a handle to the next page link. But it doesn't need to know anything about how that link is represented, or the link mechanics, or the URI, or anything like that. The generic browser analog knows those bits, and does all that work for the consumer.
There is still a protocol that the consumer needs to understand; but that protocol is expressed in links, not in URI.
There are a few aspects of this question, and the option to choose depends on which things you want to set as a priority.
Question 1) Which is better from a REST perspective?
From a strictly REST perspective, the PATCH with { "status": "pause" } is the correct one. REST is REpresentative State Transfer. And this solution most strictly conforms to that.
Question 2) Should I use 'action' oriented endpoints?
From a strictly REST perspective, the answer would be no. That said, however, in practice there are many very good reasons to do this. One of the side effects of strictly REST API implementations is that your API can start to look and act like a web-accessible data store, rather than a self-contained service. What happens when this occurs is usually that more and more of your logic migrates into the client side of the API... with complex actions becoming implemented in the client code as multiple calls to different REST actions.
This is usually not what you want, and while it can be avoided with a carefully crafted API, it most often is not.
Question 3) What is the best practice?
There isn't one, at least not objectively. Different APIs with different purposes fit REST or action oriented calling mechanisms better. That said, I've very rarely encountered an API that was entirely RESTful and had no action oriented routines... and most of them drift that way over time anyway... if for no other reason than most APIs require some sort of search function, and strict REST has no provision for that.
So, in the end, my advice is, use REST where it works, it will make your API easier for other people to get started with... and use action oriented endpoints when the action doesn't fit into the REST concepts well. It's better to have an easy to understand action endpoint than a hard to grasp REST action that triggers magical things behind the scenes.
But that's just like... my opinion, man.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I'm designing REST API for devices management system.
Endpoints:
http://api.example.com/users
http://api.example.com/devices
I want to achieve that there is an endpoint that will do some action on selected device. Something like that:
http://api.example.com/devices/1/send_signal
I know that is not REST compatible and I'm looking for suggestions to make it the right way.
I was thinking about adding another endpoint like:
http://api.example.com/calls
So when user send POST request with let's say deviceId parameter to that endpoint there will be new entry into the database (to have history of all calls and who called the function) and at the same time calls that function on specified device.
Would it be great architecture and REST compatible?
You are right about your hunch. It is not proper REST. Sometimes that is OK, but most often, it is a sign that something in your Domain needs redesigning.
Quite often, there is a domain model waiting to be discovered. Most often, things like "send_signal" are telling you that you've modeled your API too close to some library, backend service or database. An API, after all, is the interface you provide.
AS I've written before: The R in REST stands for resource (which isn't true.... etc).
Think in resources. Not in procedures or calls, or internal tools, backend services or architecture of your system. That is your stuff. The API-user should only be bothered with (clean) abstractions that make senses to the API-user.
Both /call and /.../send_signal bother too much about procedures and internals.
What do you want to do with a device? You want to turn it's camera on? That would be an update to the Camera model on the Device with ID 1337:
PUT /device/1337/camera { power: "on" }
You want a device to bzip up some log files and send them to a debug-server? You're creating a DebugSession model:
POST /device/1337/debug_session { delivery_bucket: 42, compress: "bzip" }
You want a device to send a message to some server? Create a Message on a Device:
POST /device/1337/messages { to: john, body: "Hello World" }
And so on.
That is REST. In REST you model your domain models carefully. Lots of REST servers are really poor because they are very thin wrappers around some relational databases, and suffer from far too much leaky abstractions. Lots of other REST servers are really poor because they are written far too close around backend services, jobs being ran, or other internal details.
If I want to start a new server, I want to say:
POST /server/ { region: eu-1, size: xl, disk: 1MB }
And not:
POST /resources/blockdisks/create { size: 10GB } => 1337 is created
GET /resources/blockdisks/1337?include_attrs=mountpoint,format
GET /servers/available/map_for/eu-1?xl => DB-Zfaa-dd-12
POST /servers/reserve { id: DB-Zfaa-dd-12, attach: { id: 1337, mountpoint: /dev/sdb2, format: zfs }
(I'm not making this up, I had to deal with such API's they are a PIAS to use, and quite certainly an even bigger PIAS to maintain)
The lesson here: the first exposes a domain model of a Server, with few attributes only interesting to the user of the API. The second is modeled far too close around all sorts of internal tooling, and systems.
Edit: and all this completely ignores the even more important REST-part: discovery. Links, headers, redirects, etc. But you were explicitly asking about naming resources, so that's what my answer is about. Once you have your resources, your domain models, architectured, go back to the whiteboard and do it all over: now including Links, headers, or other metadata so that your API-clients can discover what they can do and where they can do that.
http://api.example.com/devices/1/send_signal
I know that is not REST compatible and I'm looking for suggestions to make it the right way.
It is REST compatible. REST doesn't care what spellings you use for your resource identifiers.
Would it be great architecture and REST compatible?
If this is what you want, think about how you would achieve the same result with a website. The client would open a bookmark in a browser, maybe follow some links, fill in a form, and submit it. That would all work because the (generic) browser understands the processing rules for HTML, and how to manage cache meta data in HTTP, and so on. There's no point in the chain where the client needs to compose an identifier -- it either uses one provided by the server as is, or it calculates one using the generic processing rules for HTML forms.
OP clearly uses a verb, to communicate intent and procedures, which is not RESTful.
No; this is a common misunderstanding. There's nothing in the REST architectural style that says anything about human readable semantics in identifiers. URL shorteners work.
It's analogous to saying that a variable name in a program should never be a verb, because that doesn't correctly communicate intent -- the compiler/interpreter doesn't care.
The use of spelling conventions does not make a URI more or less RESTful. See Tilkov. It might even be preferable to avoid using predictable identifiers, as that ensures that consumers read the identifiers provided in the hypermedia representations, which is the point.
I think you are on the right track. Based on what you said about the system, I would probably start with this way of doing it and go from there.
POST http://api.example.com/devices/123/calls
This would send the details of the call to the API and it would intern save the call to a data store and send off an event to the appropriate subsystem or internal library to call out to the device.
Then you could have the following endpoints to get call details.
GET http://api.example.com/devices/123/calls/456
GET http://api.example.com/devices/123/calls -This would also include query parameters to limit the results in some way, probably by date.
If you want to get calls from all devices then you could to this with some query parameters restricting the result set, again maybe by date.
GET http://api.example.com/devices/calls
Just as a side note, if this is an internal API used only by your applications RPC style may be appropriate. But, by following HTTP/REST you will make your software more malleable so you can use it in more ways without making it specific to any one function.
This is a good article on REST vs RPC if you'd like to learn more. https://cloud.google.com/blog/products/application-development/rest-vs-rpc-what-problems-are-you-trying-to-solve-with-your-apis
In Rest Services,we normally use 'GET' requests when we want to retrieve some data from the server, however we can also retrieve data using a 'POST' request.
We use 'POST' to create, 'PUT' to update, and 'DELETE' to delete, however we can even create new data using a 'DELETE' request.
So I was just wondering what is the real reason behind for that, why these conventions are used?
So I was just wondering what is the real reason behind for that, why these conventions are used?
So the world doesn't fall apart!
No but seriously, why are any protocols or standards created? Take this historical scenario. Back in the early days of Google, many developers (relative to nowadays) weren't too savvy on the HTTP protocol. What you might've caught was a bunch of sites who just made use of the well known (maybe only known) GET method. So there would be links that would be GET requests, but would perform operations that were meant to be POST request, that would change the state of the server (sometimes very important changes of state). Enter Google, who spends its days crawling the web. So now you have all these links that Google is crawling, all these links that are GET requests, but changing the state of the server. So all these companies are getting a bunch of hits on their servers changing state. They all think they're being attacked! But Google isn't doing anything wrong. HTTP semantics state that GET requests should not have state changing behaviors. It should be a "read only" method. So finally these companies smartened up, and started following HTTP semantics. True story.
The moral of the story: follow protocols, that's what they're there for - to follow.
You seem to be looking at it from the perspective of server implementation. Yeah you can implement your server to accept DELETE request to "get" something. That's not really the matter at hand. When implementing the server, you need to think about what the client expects. I mean ultimately, you are creating an API. Look at it from a code API perspective
public class Foo {
public Bar bar;
public Bar deleteBar() {
return bar; // Really?!
}
public void getBar() {
bar = null; // What the..??!
}
}
I don't know how long a developer would last in the game, writing code like that. Any callers expecting to "get" Bar (simply by naming semantics) has another thing coming. Same goes for your REST services. It is ultimately a WEB API, and should follow the semantics of the protocol (namely HTTP) on which it is built. Those who understand the protocol, will have an idea of what the API does (at least in the CRUD sense), simply based on the type of request they make.
My suggestion to you or anyone trying to learn REST, is to get a good handle on HTTP. I would keep the following document handy. Read it once, then keep it as a reference
Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content
GET cached by proxies POST and DELETE not!
Yes you can create data with GET but now you have to destroy that cached.Why to do extra job.
Also maximum header sizes accepted are different because of purpose of usage.
I recommend reading the spec which clearly states how each each http-method should be used.
why these conventions are used?
They are conventions, that is, best practices that have been adopted as a standard. You do not have to adhere to the standard, but most consumers of a REST service assume you do. That way it is easier to understand the implementation / interface.
For a complex web application, one page view might require data of many different types. If you are doing client-side templating and pulling in this data from a RESTful web service, you may have to make a lot of requests to populate the page. Is there any convention by which REST requests can be combined, to receive back a single payload containing all the responses needed?
To use the Stack Exchange User page as an example, you probably would need to call at least these from the Stack Exchange API to build the page:
/users/{id}
/users/{id}/answers
/users/{id}/reputation
/users/{id}/tags
/users/{id}/questions
...etc
Could the provider of such an API allow you a single request to get all that data? Especially if other root types were involved, say you had to also request /revisions/{id} and /tags to build the page also for some reason.
To be clear, I don't want to know if it's possible to provide such functionality in a web API -- I want to know if there is a standard or at least documented means of doing so.
I think we need some standard way of doing this, but until then, you're probably on your own.
In the past I've had similar challenges when I wanted to do transactions spread across multiple resources. I invented new resources which described the actions I was about to make more clearly (subtracting 5 from account A and adding 5 to account B becomes a transaction with from and to members).
Maybe a similar (but more general) approach could be applied here by using another REST call as container;
POST /batchRequests { requests: [
{ method: 'POST', url: '/resource', payload: { ... } }
], transactional: false }
Which in turn returned a "BatchRequest" object containing results. It's pretty close to what Facebook did as well.
I think that might be against REST principles, no? i.e. the unique URI per object representation and its payload. Wouldn't it make things worse? Given that it's not TI calculator but a modern computer capable of parallel HTTP requests verses a single one that'll take as long as the logest of them all.
Don't think there is a standard, but here's an example -- https://developers.facebook.com/docs/reference/api/batch/
I know I am very late, but maybe my thoughts could help others...
My solution is a bit different.
I store the resources in a single uri (unified resource identifier) per resource.
User
GET /user => INDEX
PUT /user => CREATE (RETURN LOCATION HEADER)
GET /user/{id} => FIND
POST /user/{id} => UPDATE
DELETE /user/{id} => REMOVE
Messages
GET /user/{id}/message => INDEX
PUT /user/{id}/message => CREATE (RETURN LOCATION HEADER)
GET /user/{id}/message => FIND
POST /user/{id}/message/{id} => UPDATE
DELETE /user/{id}/message/{id} => REMOVE
Friends
GET /user/{id}/friend => INDEX
PUT /user/{id}/friend => CREATE (RETURN LOCATION HEADER)
GET /user/{id}/friend => FIND
POST /user/{id}/friend/{id} => UPDATE
DELETE /user/{id}/friend/{id} => REMOVE
The resulting content-type can get changed through a HTTP-Header, the client needs to specify.
Accept: "application/vnd.com.example.api+json; version: 1.0;"
Currently it is the Accept HTTP-Header field, that tells the server which version and which content type to use.
To keep the browser or proxy cache functionality, i decided to return the Vary HTTP Header field on my api, with all content changing HTTP-Headers in it, so that browsers can correctly differ between resources, by uri and headers.
Vary: "Accept, Accept-Language"
The biggest problem is, how to combine resources to prevent the client from opening too much tcp connections at once.
As example: If you query the user list from my API via /user, the API will return an array of user objects in the desired content-type (JSON,XML,HTML).
I won't go into detail, as there is pagination and filter/search support available to.
Each of the user objects does has dependent resources, like friends and/or messages.
There is a very good structured standard called HAL (Hypertext Application Language) which provides some easy ways to combine a resource with its dependent resources or linked resources. It uses JSON to represent the data.
Have a look at http://stateless.co/hal_specification.html by Mike Kelly.
But that solution also doesn't combine resources in one call, it just sends the uri of the dependent or linked resource with the payload to the client.
This will let the client decide which additional informations to show.
And of course, all the caching functionality, which is very important, is working.
Most of the traffic, when browsing through resources, will be duplicated requests that can be cached very easy.
If u example given want to show the number of friends or number of messages of a user in the user list, think about adding the dependent resource as a key to your result.
Example User Response (JSON)
{
id: 1,
email: test#test.com,
...
friends: {
count: 1,
_links: [{
'id': '2',
'name': 'Peter Parker',
'uri': '//api.example.com/user/2'
}]
},
messages: {
count: 1,
_links: [{
'id': 'x4gZ6',
'subject': 'Testmessage',
'uri': '//api.example.com/user/1/message/x4gZ6'
}]
},
...
}
Now let's speak about how to prevent the use of multiple TCP Connections!
There is a very simple and good approach for that...
Why not use:
Connection: "keep-alive"
This will give a client the possibility to query as many resources at once as needed.
While all resources are queried via a single TCP connection to the server.
I know there are other concerns with keep-alive connections, so feel free to discuss with me about all the ideas.
Thanks!
I'm very late to this party, but I've been looking for some lit online on the topic of balancing clean REST design vs the realities of an actual web site. I've found the usual "reduce http requests for performance" but no good essays on good practices with an eye toward tradeoffs. (Commenters feel free to point me in a direction!) And what the hell, no marked answers yet.
Not sure whether you're asking whether it's possible for other people to make your life easier by doing this, or whether you're asking because you are designing an API. Your question says other people so here we go.
Could the provider of such an API allow you a single request to get all that data? Especially if other root types were involved, say you had to also request /revisions/{id} and /tags to build the page also for some reason.
To be clear, I don't want to know if it's possible to provide such functionality in a web API -- I want to know if there is a standard or at least documented means of doing so.
The short version: I haven't seen a lot of good essays on the subject. REST's popularity may be young yet for a good academic consensus-style set of answers. Where I can get away with it, I do what I have to do and I worry less about how pure my design is re: an acronym like REST. But I'd probably err towards a purer standard (again, e.g. REST) implementation if I were the provider for a big, public API (see below).
It's possible, and I've sullied many a pure REST design in my own applications to achieve what I needed in terms of performance. Mainly RPCs or combining resource gets/updates, to minimize the number of HTTP requests, into something a modern Frankenstein web developer might produce.
Could the provider of such an API allow you a single request to get all that data?
Technically s/he certainly could do that. But if I were the publisher of a popular, public-facing API I'd probably use a more "pure" REST approach because simplicity, usability, and maintenance now take on a whole new significance if a lot of strangers will be using it. Performance, for me and for consumers, may be lower priority in this case than it would for an enterprise app for which I'm both consumer and provider.
As usual, the developer must decide the appropriate balance between speed of implementation, clean design, maintainability, performance, and a zillion other things. (That decision already started with choice of language -- Python/Ruby vs Java/C# vs C++ vs...)
I've been reading up on 'real' RESTful APIs for a few days now, and I think I'm near to groking what it's about.
But one of the things that I stumble on is that I can't even begin to imagine how one would write a client for a 'real' hypermedia API:
Most of the examples I've read talk about browsers and spiders, but that's not especially helpful: one is human-directed and 'intelligent', the other is dumb and 'random'. As it stands, I kind of get the impression that you'd need to learn AI to get a client working.
One thing that isn't clear to me is how the client knows which verb to use on any given link? Is that implicit in the 'rel' type of the uri? The alternative (reading here) seems to be using xhtml and having a client which can parse and post forms.
How likely is it that a link will change, but not the route to the link?
In most examples you see around, the route and the link are the same:
eg. if I want to set up a client which will bring me back the list of cakes from Toni's Cake Shop:
http://tonis.com
{ link: { type : "cakes" ; uri : "http://tonis.com/cakes" } }
What happens when Toni's becomes Toni's Food Shop, and the link becomes http://tonis.com/desserts/cakes?
Do we keep the initial cakes link at the root, for reverse-compatibility? And if not, how do we do a 'redirect' for the poor little agent who has been told "go to root, look for cakes"?
What am I missing?
Ok, I'm not a REST expert either, I've been reading much related stuff lately, so what I'm going to write is not my experience or opinion but rather a summary of what I read, especially, the REST In Practice book.
First of all, you can't escape from having some initial agreement between client and server, the goal of REST is to make them agree on the very minimum of things which are relevant to both of them and let each party care about their own stuff themselves. E.g., client should not care about links layout or how the data is stored on server, and server should not care about a client's state. What they agree on in advance (i.e. before the interaction begins) is what aforementioned book's authors call "Domain Application Protocol" (DAP).
The important thing about DAP is that it's stateful, even though HTTP itself is not (since any client-service interaction has state, at least, begin and end). This state can be described in terms of "What a client can/may/is expected to do next": "I've started using the service, what now? Ok, I can search items. Search this item, what's next? Ok, I can order this and that... etc"
The definition of Hypermedia content-type is being able to handle both data exchange and interaction state. As I already mentioned, state is described in terms of possible actions, and as comes from "Resource" in REST, all actions are described in terms of accessible resources. I guess, you have seen the acronym "HATEOAS (Hypermedia as the engine of application state), so that's what it apparently means.
So, to interact with the service, a client uses a hypermedia format they both understand, which can be standard, homegrown or a mixture of those (e.g. XML/XHTML-based). In addition to that, they must also share the protocol, which is most likely HTTP, but since some details are omitted from the standard, there must be some idioms of its usage, like "Use POST to create a resource and PUT to update". Also, such protocol would include the entry points of the service (again, in terms of accessible resources).
Those three aspects fully define the domain protocol. In particular, a client is not supposed to know any internal links before it starts using the service or remember them after the interaction completes. As a result, any changes in the internal navigation, like renaming /cakes to /f5d96b5c will not affect the client as soon as it adhere the initial agreement and enters the shop through the front door.
#Benjol
You must avoid to program clients against particular URI's. When you describe a link main importance has it's meaning and not URI itself. You can change the URI any time, though this shouldn't break your client.
I'd change your example this way:
{"link": {
"rel": "collection http://relations.your-service.com/cakes",
"href": "http://tonis.com/cakes",
"title": "List of cakes",
"type": "application/vnd.yourformat+json"
}}
if there is a client which consumes your service, it needs to understand:
link structure itself
link relationships(in this case "collection" which is RFC and
"http://relations.your-service.com/cakes" which is your domain
specific link relation)
In this case client can just dereference address specified by "href" attribute and display list of cakes. Later, if you change the cake list provider URI client will continue to work, this implies that client still understands semantics of your media type.
P.S.
See registered link relation attributes:
http://www.iana.org/assignments/link-relations/link-relations.xml
Web Linking RFC: https://www.rfc-editor.org/rfc/rfc5988
I'm trying to develop a simple REST API. I'm still trying to understand the basic architectural paradigms for it. I need some help with the following:
"Resources" should be nouns, right? So, I should have "user", not "getUser", right?
I've seen this approach in some APIs: www.domain.com/users/ (returns list), www.domain.com/users/user (do something specific to a user). Is this approach good?
In most examples I've seen, the input and output values are usually just name/value pairs (e.g. color='red'). What if I wanted to send or return something more complex than that? Am I forced to deal with XML only?
Assume a PUT to /user/ method to add a new user to the system. What would be a good format for input parameter (assume the only fields needed are 'username' and 'password')? What would be a good response if the user is successful? What if the user has failed (and I want to return a descriptive error message)?
What is a good & simple approach to authentication & authorization? I'd like to restrict most of the methods to users who have "logged in" successfully. Is passing username/password at each call OK? Is passing a token considered more secured (if so, how should this be implemented in terms of expiration, etc.)?
For point 1, yes. Nouns are expected.
For point 2, I'd expect /users to give me a list of users. I'd expect /users/123 to give me a particular user.
For point 3, you can return anything. Your client can specify what it wants. e.g. text/xml, application/json etc. by using an HTTP request header, and you should comply as much as you can with that request (although you may only handle, say, text/xml - that would be reasonable in a lot of situations).
For point 4, I'd expect POST to create a new user. PUT would update an existing object. For reporting success or errors, you should be using the existing HTTP success/error codes. e.g. 200 OK. See this SO answer for more info.
the most important constraint of REST is the hypermedia constraint ("hypertext as the engine of application state"). Think of your Web application as a state machine where each state can be requested by the client (e.g. GET /user/1).Once the client has one such state (think: a user looking at a Web page) it sees a bunch of links that it can follow to go to a next state in the application. For example, there might be a link from the 'user state' that the client can follow to go to the details state.
This way, the server presents the client the application's state machine one state at a time at runtime. The clever thing: since the state machine is discovered at runtime on state at a time, the server can dynamically change the state machine at runtime.
Having said that...
on 1. the resources essentially represent the application states you want to present to the client. The will often closely match domain objects (e.g. user) but make sure you understand that the representations you provide for them are not simply serialized domain objects but states of your Web application.
Thinking in terms of GET /users/123 is fine. Do NOT place any action inside a URI. Although not harmful (it is just an opaque string) it is confusing to say the least.
on 2. As Brian said. You might want to take a look at the Atom Publishing Protocol RFC (5023) because it explains create/read/update cycles pretty well.
on 3. Focus on document oriented messages. Media types are an essential part of REST because they provide the application semantics (completely). Do not use generic types such as application/xml or application/json as you'll couple your clients and servers around the often implicit schema. If nothing fits your needs, just make up your own type.
Maybe you are interested in an example I am hacking together using UBL: http://www.nordsc.com/blog/?cat=13
on 4. Normally, use POST /users/ for creation. Have a look at RFC 5023 - this will clarify that. It is an easy to understand spec.
on 5. Since you cannot use sessions (stateful server) and be RESTful you have to send credentials in every request. Various HTTP auth schemes handle that already. It is also important with regard to caching because the HTTP Authorization header has special specified semantics to caches (no public caching). If you stuff your credentials into a cookie, you loose that important piece.
All HTTP status codes have a certain application semantic. Use them, do not tunnel your own error semantics through HTTP.
You can come visit #rest IRC or join rest-discuss on Yahoo for detailed discussions.
Jan