Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have a rails platform that I maintain. It has a lot of different web applications built on top of it. However now a client is asking for an API so that they can keep users on their site, but take advantage of some of the automated tasks we have.

The platform is used to build insurance applications and allows for their purchase online, as well as providing ways to download documentation related to your policy.

So my question when building the API is this:

When I have to do a lot of things, like validate, create a user, user profile, and policy, pretty much at the same time. Should I make 4 separate API calls, and make the client build 4 calls on their side. OR should I have one call that excepts a lot of parameters, that validates the client and creates all 3 of those things at the same time, simplifying things for the client?

The client, in this case, gets all of the required information at the same time, so its not like there is a natural flow in their application where it pauses and they can make an API call to my platform.

Having been on the client side using many API's before, my gut is to make it as simple for the client as possible and have them make just one call. However this is leading to rather large functions in the API, which I'm not a fan of either.

How do you suggest I tackle this?

As a note, I am not very confident in the clients ability to implement a complicated API on their side.

share|improve this question

4 Answers 4

up vote 28 down vote accepted

How about doing both? Have a "low level" (so to speak) API that exposes functions of the system and have another "layer" that exposes services that a client might want to do. This layer would use the necessary low level API's required but those are still exposed if the client wants them.

UPDATE: To also include some of the great points and comments made by others.

  1. Consider if the client is ever going to need to call one of the smaller API methods e.g. Is it feasible to call createUserProfile without also calling createUser? If not then don't expose that method. Thanks NoobsArePeople2

  2. A simple but excellent point. Key point with exposing something in an API - you can't ever unexpose it. Expose the minimum necessary to function and then expand rather than exposing everything and... well, then its naked and making changes can be embarrassing and awkward. Thanks MichaelT

share|improve this answer
9  
+1 Was gonna say something like this. Another question to ask: would you ever do any of these things in isolation on the client. E.g., would the client ever need call to createUserProfile without also createUser? If not then don't expose it. –  NoobsArePeople2 Jan 22 '13 at 19:20
3  
@NoobsArePeople2 excellent point on the if not needed then don't expose it –  dreza Jan 22 '13 at 19:39
7  
Key point with exposing something in an API - you can't ever unexpose it. Expose the minimum necessary to function and then expand rather than exposing everything and... well, then its naked and making changes can be embarrassing and awkward. –  MichaelT Jan 22 '13 at 21:56
1  
@ryanOptini yes, that's the line I would go down. But if you design those calls in an API fashion exposing them layer should not be a problem. –  dreza Jan 22 '13 at 23:05
1  
@ryanOptini What dreza said. –  NoobsArePeople2 Jan 22 '13 at 23:54

I think your gut feeling is right - make the API simple for consumers. To some extent, this is the philosophy behind Consumer Driven Contracts.

More specifically, the API should expose suitable business use cases. Consider the business domain at hand - is there really a need for those low-level functions? What is the drawback of encapsulating them? Large functions in the API are not a problem in and of themselves. What would be a problem is if a large function sequences operations that may need to be partitioned to allow consumer intervention.

share|improve this answer
1  
Also, the simple API doesn't necessarily mean large functions. The API function can simply be an "orchestrator" which calls a few internal library functions, which in turn call other functions, until you have the right level of granularity in your code. –  Chris Jan 22 '13 at 20:42

I think you're looking at it in the wrong way. Don't worry about large | small calls or lots of | few calls.

Think about the business objects and the actions that can be performed with | for | against those objects.

You've got:

  • Users
  • Policies
  • Rates
  • ...

So you should create API calls around those objects.

  • User.Create
  • User.UpdatePassword
  • Policy.Validate
  • ...

The idea is to create atomic or near-atomic operations based upon the business objects and their actions. This will simplify design and coding - calls that do what the business object should do which matches the mental model or expectations of the programmers. When the programmers or architects are discussing requirements with the business analysts then they can all use the same terminology and general flow of operations.

The problem with larger, all-in-one type calls is the risk of side effects. If Policy.Create also spawns a User and triggers some other action, then that would break the expectation of the programmers. Likewise, lots of small calls force the programmer to remember to call A and then B and then C in order to perform a "single" business operation.

And how you name the calls will be based upon what Rails and your supporting web services will support.

To be more prescriptive, this will create some calls that take a number of parameters and may have multiple calls on the back-end that are obscured to the client. You will also end up with some fairly quick / simple calls where the API is little more than a wrapper to the underlying routine.

share|improve this answer

Personally, I like APIs that:

  1. are optimized in a way that common use cases can be easily performed
  2. calls related to CRUD operations are batch oriented or have batch versions
  3. allows reflection (so people writing plugins or bindings for other computer languages can automate the process)
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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