Architecture: API as core for a website & mobile-app
Asked Answered
A

3

6

I have different questions about a full architecture idea. I hope someone with great experience could help me out because I am pretty much getting stuck in all possibilities.

I'm planning to rewrite a community website. Our customer wants to make use of native mobile apps in the future. So I will need to take this into account. Because of this I have decided to create a 100% REST API architecture based on the PHP framework Kohana. I have choosen Kohana because this makes scaling the internal API to a other server very easily without much extra effort. (Kohana threats internal url requests not as HTTP so there isn't much overhead in the beginning and can scale to HTTP with some minor code changes).

At first the API will be private, but later on we might make it public to let more services connect to us easily.

De basic REST structure is as follow:

  1. /cats
  2. /cats/1
  3. /cats/1/custom

'custom' could be 'childs' for instance.

same goes for:

  1. /ads
  2. /bids
  3. /users
  4. /banners
  5. etc..

These are perfect entities for the API because the mobile app will definitely use all this functionality.

So we can conclude the core of the website is REST. So basically I want to make the website a client of the API just like the native app in the future. This way maintenance seems much easier.

What worries me though is the fact that there is much more than this (managing uploaded files, invoicing, automails for invoicing, automails for ads and so on). Uploading files needs to go through the website to the API. Is this common practice? If I do not do this, the website would do upload logic, which makes the site no client anymore and the app itself. Hence the mobile app can't even upload and both API and website need to know the upload folder (duplicate logic).

I thought of creating the following modules:

  1. community-api
  2. community-website

Api seems to be the core then. But.... what about cronjobs etc? Actually they should not be part of the website, as this is just a 'client'. I feel they should interact directly with the model or API. So basically the API gets more like a gateway to the core and thought I need this:

  1. community-core
    • Models
    • Cronjobs
    • Auto Mailings (part of cronjobs)
      • Invoices etc
  2. community-api
    • Interact with models in core through HTTP
  3. community-website
    • Website
    • Admin

The core cronjobs are a exception to the REST structure. They are the only one that can change data without going through the api. At least that was my idea because they belong in the core and API is on top of the core.

But by design that seems just wrong. Manipulating should only go through the API!

Alternative:

  1. community-core
    • Models
  2. community-api
    • Interact with models in core through HTTP
  3. community business
    • Cronjobs
    • Auto Mailings (part of cronjobs)
      • Invoices etc
  4. community-website
    • Website
    • Admin

This look better by design to me. Mindmap illustration
(source: mauserrifle.nl)

Main Questions

1)

Should cronjobs manipulate through the API or Core models?

2)

My invoice cronjob needs a template pretty much the style of main website of course. But if my cronjob is part of business or core it won't have knowledge of my main website. What makes sense to solve this?

3)

My website will be using mustache as a template engine. (both php and javascript can parse these templates). I thought using the api directly for ajax calls but then realized:

The site gets data from api, formats timestamps to dates (Y-m-d) for the template and then renders. If I let javascript call the api directly, javascript must have logic too (formatting). This is duplicate code! Feels like the only solution is calling the website for ajax (which calls the api and formats) and returns the formatted json. Am I right?

But.... simple calls like deleting a ad can go through the api directly (e.g. DELETE: /ads/1

I get a mix of calls....

Any better solution for this?

4)

Overall: Is my architecture too complex? Any alternatives I should consider?

I would love to hear your feedback!

Alegar answered 26/2, 2012 at 13:11 Comment(0)
C
3

Once I've heard that a good way to develop a web application is to develop an API-Centric Web Application. The thing is, to me, if you couple the main service to the public API, building an API-Centric application, you lose the whole point of developing a public API at all.

Cayla answered 27/2, 2012 at 12:51 Comment(4)
I assume your last sentence is positive? (The fact you already have a public API by building it API-Centric?) Thanks for that article, it refers to the twitter blog that inspired me to use this way of building, so definitely going to read that one too and come back to this topic later :)Alegar
Ok most of the article I already got implemented (the kohana way). I got a good feeling about creating the website as client of the API. Still uncertain where to put cronjobs etc (which is internal logic). I also have to build a admin (part of website) to manage all of the extra entities, it feels like a overhead of work :/ Then again, once build... plenty of possibilities in the future. Tips for that?Alegar
That's exactly my point. There is the need, in almost 100% of cases, to have specific application related features, such as cronjobs, that don't really fit to an API-Centric approach. That means you should, in my point of view, have webservices decoupled from the main application, such as wsdl's.Cayla
Thank you for your answer. I started building already and the more I get working, the better this architecture gets within Kohana! Again thanks for the article!Alegar
A
2

This doesn't seem logical to me.

Yes, the API and the website and what ever might come next are separate things and website should be a client to the API itself but since it will simplify things greate, I believe that you should RE-USE the domain-classes to build and base your web-site logic. This way you can use all the same code base and handle all your issues including ads, invoicing and of course file uploads with ease.

For the public API, it should be on a separate box if possible re-using the same domain classes but with different authentication methods so that whatever problem might occur, it won't affect the main service.

Your cron-jobs should only be used to fire the call through the API itself and those calls should be made on the main app (website through the API)

If you build your website without repeating-yourself, as in, using the same code as the base and wrapping the web-app around it, you won't have the issue raising in q#2.

Same thing applies for question number 3. If you wrap the website around the API, the website can use the api itself without being a separate entity.

Your architecture seems complex but if you do these things, it will be simple. ;-)

Good luck!

Atonsah answered 26/2, 2012 at 21:33 Comment(2)
Thanks for your response. If i understand you correctly: 1. There is a core with internal processes like crons, mailings, ORM, etc (including imgs for pdf creation) 2. The API uses this core to make everything public 3. The website will be a client using the API only. So concluded: if the API breaks down, the website is down too, but the automatic processes will continue working? I will need to build a admin panel too. I should put this in the website as client too right? Otherwise i get 2 access points. Feels like extra work making everything work through the API, but eventually pays backAlegar
Hello again. #1 correct. Core with all the internal process AND a copy of API. #2 a second installation (on a different linux box-vps API ONLY {for public} #3 website can either be wrapped around #1-core OR on a separate box using the API of #1 core. So: 1 linux box for DB ONLY. 1 linux box for Public API. 1 linux box for private API & domain classes and website (or website also can be a different box using this api through internal networking for security). This should not be extra work because PHP classes will be %100 the same but exist in two boxes, for scalability and security. Good luck.Atonsah
P
0

REST is just one way to initiate a request. Your core code that processes the request shouldn't be tightly coupled to the REST interface, or HTTP for that matter. I would advise designing your REST API as a simple mapper to an include file or something similar. Your cron could then bypass the whole REST API and just include the file directly. Separate the request interface from the code that does the actual processing.

Perform answered 26/2, 2012 at 23:27 Comment(5)
Kohana has an awesome sub-requesting system already, there's no need to hack things.Equilibrist
I agree about the hacking. The point itself i don't understand. What do you mean by bypassing the REST API?Alegar
A REST API is more of a documented interface for interacting with your system from an external source. You need to parse the request and figure out if it is valid. Cron is a "trusted/internal" source that can call routes directly, no parsing of a request needed. REST is your neighbor knocking at the door asking for something, cron is your roommate who is already inside and knows where everything is.Perform
So if I understand correctly: Crons directly communicate with model classes, dao's etc(PHP). REST interface parses (url) requests, uses the PHP classes to find the data and returns the asked datatype (json) for external sources. The website you visit as a visitor will be a external source using this json. You say: "Cron is a "trusted/internal" source that can call routes directly, no parsing of a request needed". I assume you mean by routes just the method calls of classes? It sounds confusing as you might mean urls by routes and still use REST.(In kohana routes are the url to a controller)Alegar
By routes I mean Kohana routes. In one scenario, cron could call Route::set directly, whereas the REST interface needs to parse the URL first. Crons usually don't require input or output. In another scenario, cron could call Request::instance directly. Sorry, Kohana isn't my strongest framework.Perform

© 2022 - 2024 — McMap. All rights reserved.