1

I'm building an api and a bit into the development I realized that I constantly change the order of the page and pageSize parameters.

Currently I use C# and javascript, so the method declaration looks something like this:

public IEnumerable<Order> Get(int pageSize = 9, int page = 1, string name = null)

And the client code:

this.get =  function (name, pageSize, page) {
    // Do stuff..
}

But a lot of the times I've ended up writing:

name, page, pageSize // note that page is before pageSize.

And it also has an http endpoint, which currently looks like this (with pageSize first):

www.example.org/api/orders/9/1

Or should it look like this (with pageSize last):

www.example.org/api/orders/1/9

What's the logical way to call an api? By setting the page first, or pageSize first? Is there a best (or common) practice?

Argument for setting pageSize first:

  • The consumer may simply define the number of items to fetch without setting the page.

Argument for setting page first:

  • The consumer may simply shift page and rely on the servers pageSize.
2
  • 2
    I can't think of any strong argument for having it one way over the other (although you should of course endeavour to have your API design be consistent in this). Personally, I'd probably suggest your API do away with the "paging" concept and instead just say "get my this many starting from this index".
    – TZHX
    Sep 9, 2016 at 12:18
  • To start with the URL, I would use something like www.example.org/api/orders?pageSize=9&page=1 and problem solved here. Otherwise it wouldn't really matter that much, my opinion for what it's worth: First define the thing (pageSize) then number the things (page to use). Sep 9, 2016 at 12:32

1 Answer 1

1

Required on the left. Optional on the right.

If the languages you are using are suffer from a lack of named arguments you have to rely on position. This is the traditional positioning.

There are ways around that. The Josh builder lets you simulate named arguments in these languages.

However, before resorting to that let's review basic telescoping.

Get(String required1, int required2); // A

Get(String required1, int required2, int optional); // B

In C# method overloading allows these to call separate method bodies. Using that you can simply implement A by defining the optional and passing it and the rest to A.

If the default value for the optional is simply a constant then this is a handy way to do it all in one:

Get(String required1, int required2, int optional = 42); // C

However, since 2010 C# has had named arguments. This means callers can avoid the positional confusion by using the names of the arguments they mean when they call.

For you, that might look like this:

Get (name: "MyName", page: 1, pageSize: 9)

Now the order doesn't matter.

This is critically important when there is more than one optional with a default value. Without named arguments you can't pick and choose which optionals to leave with their default values.

In Javascript there is no true overloading but there are some good practices. They also put required on the left and optional on the right.

In URL's folders are usually required. Optionals usually go in the query string. Fan's of semantic URLs might argue against that but if you want it to be optional then you shouldn't require it. A query string lets you have multiple optionals that are named.

3
  • Thank you for your answer. The problem here is that in C# all the parameters are optional. But it's worse when using the http-endpoint (web api). Then it's not as obvious.
    – smoksnes
    Sep 9, 2016 at 13:17
  • In either case you can't use positional arguments unless you're willing to always dictate every value. Name arguments let you pick and choose what to leave default. Sep 9, 2016 at 13:24
  • Required on the left. Optional on the right. It is hard to say which argument is required or not. If I see 3 arguments In any signature, the first I supose is that all 3 are required. In the case of the answer I would suggest the natural order of the language: from / to
    – Laiv
    Sep 10, 2016 at 12:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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