3

My goal is to have a REST endpoint that I can push AJAX requests to, have those requests be parsed, potentially push some data into the DB via a channel, and then return a JSON status message. I don't want to have to put PHP into a template to accomplish this, and am happy to write an add-on of some sort.

Please don't suggest add-ons. I want to know how I would go about writing my own add-on to accomplish this.

My question:

From a high level, how would I start writing this add-on? Specifically, how would I route a custom URL to my add-on code? What type of add-on should I be building for this (i.e. Module, Extension, something else)?

This is something I've done a number of times with other web frameworks (including CodeIgniter), but for some reason I'm finding it very difficult to get information on how this would be done in EE.

EDIT: I've tried to make this question more clear. I'm specifically looking for advice about add-on creation. Based on my re-reading of all the EllisLab add-on docs and a lot of time searching the web, I'm starting to feel like this isn't something EE can do without an incredible amount of hacking. I'm really hoping that's not the case.

5

It's certainly possible without hacking. Just that the EE documentation isn't particularly helpful on how to handle this sort of thing.

Basically, you want to write a Module. Then you need to register an "action" in your module's install script:

$data = array(
    'class'     => 'Module_name' ,
    'method'    => 'method_to_call'
);

$this->EE->db->insert('actions', $data);

Bingo. This will give you an endpoint which you can use to create your API (this is how all EE modules work when handling form submissions from the front end). You action will get an ID like 123, and will be accessible at http://www.example.com/index.php?ACT=123. This will then call the method you specified in the install script (this method must be defined in your class in mod.addonname.php).

Now you can check input data, access the database, return JSON... whatever you like. For an example of this in action, check out FreeMember.

Note: This doesn't involve any routing, but it builds a perfectly valid web service endpoint. If you want custom routing, the only way to go is to create an extension using the sessions_end hook, and add your own router code which checks for specific URLs and handles the response. It's WAY easier to just work with EE's built in ACT handling.

  • 1
    Awesome! Thank you, this is exactly what I was looking for. – Gavin Anderegg Mar 6 '13 at 12:15
2

I've thought more about this. Based on the pre-condition you're building a custom addon to handle this, the only way I can see it working would be to either :

  1. Create a dummy top level template group (ie. called 'api' with a sole tag to your custom addon : {exp:restful_api:handle}. From within there you could do any and all the parsing/restful interactions that you'd need. That's a fair amount of work and you'd need to be careful EE's not fighting you with parse orders or other built in core mechanisms.

  2. An option would be to try and see if the core_template_route hook fires early enough to be of use to you. If that fires early enough, use that to hook against the calls, do some basic filtering, and if the route appears to be one you want to have you're custom handling (ie. matches foo.bar/api/...) kick into your custom handling. You'd need to kill out any actual following EE handling, but if you're going custom regardless that might work.

(If the core_template_route hook fires too late, you might need to find an earlier hook. But in principle it's possible, if a bit unusual. )

  • I'll look into the core_template_route hook. I assume that if I'm using that, I'd have to be making an Extension, correct? It also sounds like I'd have to put my logic in a template if I use it, which I really don't want to do. I'm really surprised that this is turning out to be such a pain. EE seems to be the easiest system to use when not doing custom code development, but the hardest system to use when you want to :( – Gavin Anderegg Mar 5 '13 at 13:24
  • What I was thinking, was simply using that hook to jump into the processing as early as possible, then hand off to your own code. You wouldn't have to use a template for logic at all, just hand off to your own code early on, then exit the actual request early and return just your api output. The simplest thing might not be to use the standard EE handling at all if you need it fully restful though. Whatever you do will be a bit of a hack. – Joel Bradbury Mar 5 '13 at 13:34
  • Huh. Ok. Yeah, that sounds like what I'm looking for, then. I'll give that a shot. This sounds better to me than the "API app" below, as that seems like just a copy of EE's index.php with a bunch of extra core files sprinkled, and that can't easily access get_instance() for the real app. I'd like to keep everything in a single package and then read/write to my channel data using the regular API. – Gavin Anderegg Mar 5 '13 at 13:40
  • Actually, sorry, I looked again at the "API app", and it does look like it could read/write to the real app using the regular API. It still seems awfully fragile to me, as you'd have to modify app.php whenever EE's real index.php changes, and I don't think there would be a way to easily re-package it into an add-on (as it relies on circumventing the regular template loading process). – Gavin Anderegg Mar 5 '13 at 13:46
1

Switchee is a plugin that will let use switch/case logic in your EE templates and allow you to use your template more like a controller, responding with different chunks of code based on the variable/s you test against. I will commonly use it and test against EE's segment variables so I can combine a channel listing and single entry into the one template, creating a more succinct URL structure than the standard EE template-group/template/variable URL. You could also use it to setup a simple API.

There are also a few routing add-ons for EE -- Freeway and Router -- that may be what you are after. I haven't used either but there is a comparison on StackExchange.

  • Thanks for your answer, but I'm not looking for add-on suggestions. I want to know how I would start building my own add-on to do this. I've edited my question to try and make this more clear. – Gavin Anderegg Mar 5 '13 at 12:06
1

One method (al-be-it a bold one), would be to side-step the EE routing and templating entirely.

Create a new folder at root level within the site, ie. called 'api'. Within that drop a custom CodeIgniter (or anything really) application that would act as your API controller.

Chris Imrie built exactly this for an EECI talk. Have a look at - EE Data API.

From the best of my memory, that's a read-only setup, but it wouldn't take a huge leap to extend it to have write functionality too.

The advantage of having it as a standalone setup, is that you'll keep full control over every part of the api that'd you'd need to implement. Which, depending on the complexity of what you're building might be a good thing. It can be fully restful, have extra authentication, etc.. anything you'd need, and it wouldn't interfere with your existing site.

  • Wow. That is quite a bold step. Especially because it requires dropping PHP files all over the EE system directories, making EE ever harder to update :( If someone went to this much trouble just to get a read-only API to work (and it does seem to be only read-only), I feel like what I'm asking for isn't something that EE can do without a crazy amount of hacking... – Gavin Anderegg Mar 5 '13 at 12:13
  • You're not really dropping things all over the EE system directories, just in a single directory outside of the standard /system dir. Given that you're thinking about it being a fully restful api, actually implementing that within EE would be a real pain, because the EE core will be trying to intercept all the actions. – Joel Bradbury Mar 5 '13 at 12:50
  • There's also a /system/ folder which looks exactly like the default EE system layout, and has extra files in the controlers/, core/, and models/ folders. It looks like those need to be in the system/ folder. – Gavin Anderegg Mar 5 '13 at 13:19
  • True. Sorry I missed that. That's specific to Chris' implementation though. Realistically speaking it could be done without it, and just having a receiver component in a custom addon, that'd be within the normal EE third_party dir. Then all you'd be using the 'api' standalone for would be to get around the native EE routing, and then handing off to your custom addon for actual core EE logic parts. It'd be messy, but would work for what you'd need. – Joel Bradbury Mar 5 '13 at 13:23
0

I've used a combination of Switchee and Freebie for this kind of thing in the past. Switchee sets up cases for a segment variable and Freebie makes EE ignore certain words so it doesn't reroute the template or alter how a tag is displaying entries. For instance, using the same template to show a success message after submitting a contact form.

For example, this contact form would redirect to the same URL with the word /thanks added upon successful form submission:

{exp:switchee variable = "{freebie_2}" parse="inward"}
  {case value="thanks"}
    Thanks for submitting the contact form!
  {/case}
  {case default="yes"}
    *(contact form code goes here)*
  {/case}
{/exp:switchee}

Note: You have to use {freebie_2} instead of {segment_2} to include words in Freebie's segment list that EE would otherwise ignore.

  • Thanks for your answer, but I'm not looking for add-on suggestions. I want to know how I would start building my own add-on to do this. I've edited my question to try and make this more clear. – Gavin Anderegg Mar 5 '13 at 12:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.