I'm working on a CouchDB library for PHP, and so I needed to write some tests for it. CouchDB has an HTTP API so I'm basically making web requests and while I could certainly set up a test database and run full-on integration tests, there are a few limitations with that approach. Firstly: it means I'm testing the database as well, which isn't what I want and brings extra dependencies that make the tests harder to run. Also: I want to be able to test error cases, rate limiting and so on, that would be difficult to recreate reliably. Continue reading
For some years I've been creating a bundle of links covering articles I recommend for various topics in the Zend Certified Engineer Exam (if you can here looking for the bundle itself, it's at http://lornajane.net/zce-links-collection). This was done using bitly's bundles feature, which I thought was a great way to share links. In fact I had 10-15 bundles that I had created from collating all the links in a particular training course or talk, so that people didn't have to try to write down URLs as I went along. Unfortunately they sunset their bundles and then removed them completely, and I missed the announcement (it all happened quite quickly, they'd seen some abuse of the feature, it's free, all totally reasonable) BUT they also didn't respond to my support questions about how to recover the data.
It turns out, it's an undocumented feature on their API, so here is everything I know about recovering your bundle data, including the script I used to rescue my own data. Continue reading
I get a lot of complaints about an API that I maintain (http://api.joind.in) which is "missing" the ID field. This ID field is the database's primary key; if the user doesn't have access to the database (they don't), then it seems to me that the primary key probably isn't all that useful.
Instead, the API publishes each record with a unique
uri field. If this record is referred to by another record, then this full identifier will be used in every case. If this record should be included in a collection, this exact same identifier will be used there, too. You can reach the resource directly by requesting its URI. In the same way that we might refer to a website by its URL, we refer to records in RESTful systems by their URI*. If you need to store these somewhere for your own use, you can use whatever key you like with the local storage, you may even choose to use the
uri field as it is unique.
* URI stands for Unique Resource Identifier
I'm working on a project that uses a search engine to show images on a particular topic ... but I need my search to be localised since I'm in the UK and so "football" doesn't mean what a generic search engine thinks it means. Getting this working was MUCH harder than I expected, so here's a quick post on what I did so that I can remember for next time - and if this helps you as well, then great :)
Google Custom Search Engine
It's possible to set up and configure a custom search engine in Google, so you can configure some settings and the search will always use those settings. To begin, go to http://www.google.com/cse. Here you can create a search engine, give it a name and description, and then set some options. You can choose whether to search for images, or not, or images only. You can include or exclude certain sites, or search everywhere and just prefer certain sites. Continue reading
It's that time of year again, the PHP North West conference is almost upon us, and this year they are once again running a hackathon. These events are a great way either to carve out some time to get your head down and hack on an idea that's been in the back of your mind for a while, but they're also a fabulous way to get involved in collaborating on projects. At PHPNW, you'll find there are quite a lot of open source projects at the hackathon, standing by to take on anyone interested in getting involved, either just for the evening or beyond. I'll be there, representing joind.in, a tool which is used by the conference itself. So what kinds of things will there be to do and how can you get involved? Continue reading
In case you missed it, Twitter updated their APIs recently, so that you have to authenticate to use even their search APIs to return publicly-available results. This is an increasing trend for API providers, to provide either very limited or nonexistent access for unauthenticated users, I think so they can rate limit consumers that swamp them. To cut a long story short, that meant I needed to update my dashboards that keep an eye on twitter searches to do more than just call
file_get_contents in the general direction of the right URL. Continue reading
Twitter is great for one-liners, but it's very difficult to carry on any kind of advanced conversation there. Therefore when I saw this tweet yesterday, I knew I'd be picking a different medium to reply:
— Maximilian 'Berghoff (@ElectricMaxxx) June 12, 2013
The blog seems like a good place, as I can put examples and all kinds other things here, and waffle at length (which is really why I like it!). Because when condensed to tweet form, the answer is really "it depends".
REST is all about representations of resources. They might come in different formats, and they might appear at their own URI as well as in one or more collections, but essentially you just get a representation of a thing. This is great, apart from when it isn't.
- What if you want a smaller result set with only a limited number of fields?
- What if you want related data? For every resource in a collection?
While working on a book ("PHP Web Services" from O'Reilly, not out yet but soon!) recently, I was looking for some place I could make HTTP requests to, to show off how to make different kinds of requests with different tools. On my own machine, I have a couple of scripts that chatter back giving debug information about the requests that were made, but I wanted to get the tools examples going without any additional dependencies at all. I hadn't used anything like these tools before, but I found quite a few alternatives, so I thought I'd share what I came up with. Continue reading