340xYeah, so this amazing new device will, like, revolutionize the way we all look at things and stuff. Because you can touch it, things will be way better. Our lives just got a ton better. This revolutionary device will revolutionize the way we look at news and movies. Oh, and it will also change the way cities are structured.

So, in case you haven’t heard, Apple took their iPod touch, made it 5x bigger, and are now marketing it as the iPad (or “Tablet”). Where does that leave us? A portable device that’s not portable and really fucking difficult to use. The reason laptops have keyboards and pointing devices is because people don’t like on-screen keyboards. They suck. It’s necessary on small and mobile devices like the iPod touch, but on a bigger level it’s not…which why laptops exist.

So before you follow the marketing hype and buy your new $500 tablet, ask yourself “What the fuck am I thinking?! I already have an iPod, and I already have a laptop. Those swindling asslickers don’t need more of my money!”

That’s right, the iPad is a shitty in between piece of shit which is shitty and smells like shit. It’s not quite a laptop, and it doesn’t quite fit in your pocket. Stay away!! Don’t be a dweeb!

Hey, this will be short. Me and my brother just launched our event site, beeets.com, in the Santa Cruz area. Check it out, post events, give feedback. We’ve been slaving away and we’re really excited about it. Thanks!

I just stumbled onto this tonight: The Mootools plugin forge. Pretty sweet. Tons of fan-based plugins for Mootools in one spot. Check it out!

Google recently made a change to their main search page. Everything besides logo, search box, and buttons is now hidden until the page is moused over.

<rant>
What the fuck? Your search page was so simple. So clean. There was nothing to fix, nothing to make simpler. There was minimalist navigation on the top, and a few links on the bottom. It worked very well and was very good design.

You took something very simple, and tried to make it simpler. You have not succeeded. You took what you view as a problem and swept it under the rug. Your homepage isn’t simpler at all…it just LOOKS simpler at first glance. Then with first mouseover, it fades in?! What the fuck are you thinking?

This is the kind of childish effect a high-schooler learning HTML 4 would hack into his first homepage with shitty javascript. It looks nifty the FIRST TIME but after that it’s completely obnoxious and frustrating. I don’t want to wait to click on Images or News. Even if it’s 1/2 second.

To use the words of a blog commenter: “Imagine being at your desk preparing to work, but the desk chair would not appear until you try to sit down.” This is exactly how I feel.

If you really want to keep your juvenile display of javascript skillz, please give people an option to disable it so we don’t have to keep a bucket nearby in case new the homepage induces violent bouts of vomiting. Until then, I (and several others from the sounds of it) will be using Bing.
</rant>

I recently got a WRT54G v3 (an older version of a Linksys router) off of ebay. I specifically got a version 3 because it’s the best router known to man that’s under $300. If you can get one for less than $50, my advice is to take it. Up until a few days ago, it was running the stock Linksys firmware. It’s not terrible but it’s not very extravagant either. We had a power outage and after that, wireless stopped working. I tried many things, including slapping the unit with my balls to make sure this wasn’t some sort of misguided power struggle. Putting it back in its place should fix that. No luck.

I had heard many, many times about the dd-wrt firmware. One of the good things about the WRT53Gv3 is that you can install just about any custom firmware you want onto it. I’d also heard in the past about a firmware called Tomato. It’s supposedly light, lean, fast, and has great QoS (although I never even bother with QoS).

I decided to give it a shot. I’m in love. It gives you all the options you need for the things you’d want, but doesn’t bloat up the interface with extra junk. It’s simply amazing. I really think Linksys should just stop bothering to make their own shitty firmware and just install Tomato on their routers.

Unfortunately, Tomato didn’t fix the wireless problem, so I had to plug in an old nemesis Netgear router I had laying around. It starting, in memory of times past, dropping my connection every 5 minutes. Fine for browsing the interweb, but not for streaming music or “videos.” I decided to give the Linksys one more shot…and it worked! Thank god. The best router ever with the best firmware I’ve seen so far, NOW with wireless. It must have been some strange hardware issue that fixed itself.

To be fair, I’ve never used dd-wrt and therefor can’t give a good comparison between it and Tomato. If I had a few extra routers laying around, I’d try it out…but each firmware flash is a dance with the devil and I can’t afford to get / find another one.

There are probably a billion guides for this already, but whatever. If you DON’T have a ~/.bash_profile (a file that gets executed every time you start cyg):

touch ~/.bash_profile
chmod a+x ~/.bash_profile

Now that you have the file, add this to it:

SSHAGENT=/usr/bin/ssh-agent
SSHAGENTARGS="-s"
if [ -z "$SSH_AUTH_SOCK" -a -x "$SSHAGENT" ]; then
	eval `$SSHAGENT $SSHAGENTARGS`
	trap "kill $SSH_AGENT_PID" 0
fi

This will start up ssh-agent for each Cygwin shell you have open. Close your Cygwin shell (if one is open) and open a new one. Now type:

ssh-add ~/.ssh/id_rsa
[enter your password]

Voila! No more typing your stupid password every time you need to ssh somewhere. Note that if you close the Cygwin window, you’ll have to ssh-add your key again! This is good security…you can close the window when you’re done and someone who happens on your computer sitting there won’t have password-less access to any of your secure logins.

After all my research on what it means for a service to be RESTful, I think I’ve finally got a very good understanding. Once you understand a critical mass of information on the subject, something clicks and the first thing that comes in to your head is “Oh yeah! That makes sense!”

It’s important to think of a REST web service as a web site. How does a website work?

  • A website works using HTTP. If you need to fetch something on a website, you use the HTTP verb “GET.” If you need to change something, you use “POST.” A RESTful web service uses other HTTP verbs as well, namely PUT and DELETE, and can also implement OPTIONS to show which methods are appropriate for a resource.
  • A website has resources. A resource can be information, images, flash, etc. These resources can have different representations: HTML, a jpeg, an embedded video. REST is the same way. It is resource-centric. Want a list of users? GET /users. Want an event? GET /events/5. Want to edit that event? PUT /events/5. Every resource has a unique URL to identify it!
  • Resources are not dealt with directly. Instead, representations of resources are used. This can be a bit hard to grasp. What is a user? It’s a nebulous object somewhere that I cannot interact with. It is an idea, an entity. A representation is a form of the user resource I can interact with. A representation can be a comma delimited list, JSON, XML…anything the client and server both understand. How do we know what we’re interacting with? Media types:
  • As a website will tell you what kind of image you’re requesting, a REST service tells you what kind of resource representation you are receiving. This is done using media types. For instance, if I do a GET /events/7, the Content-Type may be “application/vnd.beeets.event+json” which tells us this is a vendor specific media (the “vnd”) and it’s an event in JSON format. You can pass these media types in your Accept headers to specify what type of representation you would like. These media types are documented somewhere so that client will know exactly what to expect when consuming them.
  • If you request a page that doesn’t exist or you aren’t authorized to view, a website will tell you. This is done using headers. A good REST service will utilize HTTP status headers to do the same. 200 Ok, 404 Not Found, 500 Internal Server Error, etc. These have already been defined and refined over many, many years by people who have been doing this a lot longer than you (probably)…use them.
  • A website will have links from one page to another. This is one of the main points of a REST service, and is also widely forgotten or misunderstood (it took me a while to figure it out even doing intense research). Resources in a REST service link to eachother, letting a client know what resources can be found where, and how they relate to eachother. An HTML page has links to it. So does a REST resource. Links can be structured however you like, but some good things to include are the URI of the linked resource, the relationship it has with the current resource, and the media type. This creates what’s known as a “loose coupling” between client and server. A client can crawl the server and figure out, only knowing a pre-defined set of media types, what resources are where and how to find them. This principal is known as HATEOAS (or “Hypermedia as the Engine of Application State”).
  • REST is stateless. This means that the server does not track any sort of client state. There are no session tokens the client uses to identify itself. There are no cookies set. Every request to the REST service must contain all information needed to make that request. Need to access a restricted resource? Send your authentication info for each request. It’s that simple. Isn’t it easier to track session? Not really. Maybe it’s easier on a small level, but once you start needing to scale, you will wish you’d gone stateless. Using a combination of HTTP basic authentication and API/Secret request signing, you don’t have to send over plain text passwords at all. Hell, even throw in a timestamp with each request to minimize replay attacks. You can get as crazy as you’d like with security. Or for those who prefer security over performance, use SSL.

Now for some examples. Because I’m currently working on an event application, we’ll use that for most of the examples.

Let’s get a list of events from our server:

GET /events
Host: api.beeets.com
Accept: application/vnd.beeets.events+json

{"page":1,"per_page":10}
-----------------------------------------
HTTP/1.1 200 OK
Date: Tue, 01 Dec 2009 04:12:48 GMT
Content-Length: 1430
Content-Type: application/vnd.beeets.events+json

{
	"total":81,
	"events":
	[
		{
			"links":
			[
				{
					"uri":"/events/6",
					"rel":"/rel/event self edit",
					"type":"application/vnd.beeets.event"
				},
				{
					"uri":"/locations/121",
					"rel":"/rel/location",
					"type":"application/vnd.beeets.location"
				}
			],
			"id":6,
			"title":"Paris Hilton naked onstage",
			...
		},
		...
	]
}

What do we have? A list of events, with links to the resource representations of those events. Notice we also have links to another resource: the location. We can leave that for now, but let’s pull up an event:

GET /events/6
Host: api.beeets.com
Accept: application/vnd.beeets.event+json

-----------------------------------------
HTTP/1.1 200 OK
Date: Tue, 01 Dec 2009 04:12:48 GMT
Content-Length: 666
Content-Type: application/vnd.beeets.event+json

{
	"links":
	[
		{
			"uri":"/events/6",
			"rel":"/rel/event self edit",
			"type":"application/vnd.beeets.event"
		},
		{
			"uri":"/locations/121",
			"rel":"/rel/location",
			"type":"application/vnd.beeets.location"
		}
	],
	"id":6,
	"title":"Paris Hilton naked onstage",
	"date":"2009-12-05T04:00:00Z"
}

Using the link provided in the event listing, we managed to pull up an individual event, which we know how to parse because we know the media type…but wait, what’s this? OMG, someone is trying to smear Paris!! She’s on at 8:30!!! NOT 8!!! Let’s edit…if we do a PUT with new information, we’ll be able to save Paris’ good name:

PUT /events/6
Host: api.beeets.com
Accept: application/vnd.beeets.event+json
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

{"title":"Paris Hilton naked onstage (yuck)","date":"2009-12-05T04:30:00Z"}
-----------------------------------------
HTTP/1.1 200 OK
Date: Tue, 01 Dec 2009 04:12:48 GMT
Content-Length: 666
Content-Type: application/vnd.beeets.event+json

{
	"links":
	[
		{
			"uri":"/events/6",
			"rel":"/rel/event self edit",
			"type":"application/vnd.beeets.event"
		},
		{
			"uri":"/locations/121",
			"rel":"/rel/location",
			"type":"application/vnd.beeets.location"
		}
	],
	"id":6,
	"title":"Paris Hilton naked onstage (yuck)",
	"date":"2009-12-05T04:30:00Z"
}

Holy shit, that was close. Notice we had to pass in authorization info, but now Paris won’t sue us for spreading misinformation. Phew.

What have we learned? Given one URL (/events), we have discovered two more (/locations/[id] and /events/[id]). We’ve also seen the media types in the responses that allow the client to know what kind of resource it’s dealing with and how to consume it.

Hopefully this pounds two really important points in: media types and HATEOAS. Without them, it’s not REST. You can’t just pass application/xml or application/json for every response. Sure, maybe the client can decode it, but they don’t know what it is, and without linking to other resources, they don’t know how to find anything…unless you want to document everything and never change your service.

Some other tips/points:

  • Give yourself a few initial entry points to your REST service. You should be able to discover all of the resources in it just by crawling. If you can’t, you haven’t done HATEOAS correctly. This is a lot harder than it sounds, but it’s more than useful later on. Think of your REST service like a website with good navigation.
  • Remember to implement the OPTIONS verb for your resources. It will tell the client what verbs can be used on what resources. With some decent routing built into your application, this should be a cakewalk.
  • As mentioned, you can use HTTP basic authentication for your requests. If the client is anything but a web browser, you won’t have to serve up an ugly popup login box, you can just do all that shit transparently. If you don’t want to send a cleartext password (please don’t!) you can salt the password on the client side and send it over. Hash the password again with the client’s secret for added security. Crackers will be amazed at your 1337 computer hacking skillz. You can then verify the hashed salted value on the server side. Add client-secret request signing with a timestamp for uber security.
  • Read a lot more info on REST. It seems that SO many “RESTful” services out there are half-baked and made by people who researched the topic for half a day. Some good ones to take points from are the Sun Cloud API and the Netflix API. Notice the documentation of media types and LACK of documentation on every single URL you can request. This is that loose-coupling stuff I was talking about.

That’s it for now! I wrote this as a culmination of knowledge for the last week or so of research I’ve done…please let me know if any information is missing or incorrect and I can make updates. Hope it was helpful!

Capistrano is a sexy bitch. At least it was until I spent hours trying to figure out how to deploy to multiple servers. Updated Cap, Ruby, compiled Ruby from source twice, etc etc. Capistrano just kept hanging with pushing code to two or more servers at once. Note that I am in Cygwin, if that makes a difference. Also, when deploying with no password on my ssh key, it works…hmm.

Well I added this:

default_run_options[:max_hosts] = 1

To my deploy.rb, and although it now has to deploy to one server at a time, it works. Note that for two servers this is fine. For 200 it’s not so fine. I’ll worry about that when it comes though.

UPDATE!!!! Something I never thought about until now is that you can use ssh-agent to save your keys in memory pre-deploy. Then you have a password-protected key that works with Capistrano WITHOUT doing the max_hosts hack. This is tested (on cygwin) and working for me.

This will be a short post, but pretty cool.

You can add arrays together:

	$test1	=	array('name' => 'andrew');
	$test2	=	array('status' => 'totally gnar, dude');

	print_r($test1 + $test2);
	---------------------------
	Array
	(
	    [name] => andrew
	    [status] => totally gnar, dude
	)

Wow…who would have thought. And my most recent favorite, converting objects to events. It’s a simple foreach($object as $key => $val) and putting each element into a separate array right? WRONG:

	$array	=	(array)$object;

No fucking way. Casting actually works in this case. Why does nobody tell me anything?! This is great for parsing XML because any parser normally returns an object, and quite honestly, I hate dealing with objects. All database data is by default returned as an array usually,  and it’s a pain having some data sources being objects while others are arrays. Now it doesn’t matter…if you like objects, cast an associative array as an (object), if you like arrays cast with (array). I love PHP…

This is the third post (in a row) I’ve made about REST. I’ve now read multiple explanations of REST, many of which say the same thing. Then I see implementations of these explanations, and the people who coined REST turn up their noses. I know someone has implemented REST correctly. I mean, someone out there HAS to have done it right…right? Every criticism of why a service is not RESTful uses terabytes of nit-picking jargon but somehow lacks examples on how that service could be made RESTful.

“This service is NOT RESTful because in REST, payloads are self-describing and contain references to other resources, and servers should be able to change their namespace, and two points always make a line unless one is in hyperspace.” And xyz.com’s REST API wasn’t doing this? What could they have done to change this? What IS REST about their API?

Maybe I’m dumb. Actually, no I’m not. I just can’t look at a spec and say, “Oh, I get it.” I have to see real, live examples. Why can nobody do this? It seems every HTTP “REST” service is a false implementation yet nobody can give a concise explanation of why.

I get that using only GET and POST is not RESTful. I get that every resource is a noun, and has a URL associated with it. I get that verbs are defined by HTTP and should not be used in URLs. I get that HTTP status headers should be used in conjuction with responses. I sort of get what a media type is (application/vnd.ieatmcdonaldstoomuch.cheeseburger) but do not get where it is defined. Or is this arbitrary?

Some points I have taken from all the back-and-forth involved in trying to break into an extremely elitist (and rightfully so, REST is REST) architectural style:

  • REST is stateless. All information required to complete the request is sent with the request. Every time.
  • REST re-uses existing specs. HTTP has defined some very useful verbs (GET/POST/PUT/DELETE) for us to use. It makes sense to use those instead of creating custom verbage. HTTP also has status headers for letting a client know WTF is happening. 200 OK, 506 Suck My Balls Client, etc.
  • REST maps resources to locations. I can find events by doing GET /events. I can post an event by doing POST /events. I can delete an event by doing DELETE /events/123. These URLs (/events, /events/123) are resources…an event collection and a single event. They are abstract things and a description of that thing is what is interacted with (aka “representation”).
  • REST uses media types to define resources. I’m assuming this is the “application/vnd.event+xml” content-type thing. This is very confusing for me. Where is this MIME type defined? How is it defined? How does a client consume it? WTF is going on here? Any ideas, anyone?
  • A REST service is self-descriptive. Reading one of Roy Fielding’s annoyingly-complex criticisms of bad REST implementations brings up the point that given an initial URL and a “set of standardized media types that are appropriate for the intended audience,” I should be able to completely discover all information on that service. So when I hit the homepage, I should get an XML/JSON/HTML response telling me that there are events under /events? How do I structure this response? What “media type” would this resource be? I get the point behind this, but would love to see a full implementation.

So while I’m have a lot of trouble grasping the last two points, everything else seems to make good sense. So far, anyway. I’m sure in a few minutes I’ll read another guide telling me that everything I know about REST is WRONG and I’m going to hell for even thinking the word REST without knowing exactly what it means.

Perhaps a REST web service that describes how to implement REST over HTTP would be a fun and amusing project…

UPDATE – I suppose a website comprised of HTML that describes REST would be RESTful…no need to make a “service.” Maybe this should be taken under because there seems to be a vague disseration, a few authoritative “resources” who love to use useless jargon, and a collection of blog posts that individually are all wrong, but pieced together create a somewhat workable view of that REST over HTTP should be like. So, someone should definitely get on that. In fact, I just might.