How to design my api

Hi
I want to know how to design my api, could you give me some advice:
I want to get all kindergartens of one city
1./cities/{city}/kindergartens
2./kindergartens/{city}
which url is better.

This is my DTO
[Authenticate]
[Route("/kindergartens", “GET”)]
[Route("/cities/{city}/kindergartens", “GET”)]
public class GetKindergartens : IReturn<List>
{
//Optional resultset filters, e.g. ?Cith=Xian
public string? City { get; set; }
}

It seems that you are trying to give a way to search for kindergartens,If you are using ServiceStack.OrmLite in your project, you could expose your kindergarten table via AutoQuery which would allow you to filter in a range of different ways on columns in the table. This route could be at [Route("/kindergartens","GET")].

This would allow you to do a request at the following URL to get kindergartens in a city.

/kindergartens?City=CityName
Or if they are only providing part of a city name
`/kindergartens?CityContains=PartOfCityName

Info on more filtering options are also in the wiki.

Routes for adding/updating/deleting could be at:

[Route("/kindergartens/{Id}","GET,PUT,DELETE")]
[Route("/kindergartens","POST")]

Hope that helps.

thank you. but i see the document SS do not like the odata style:
The new AutoQuery support in ServiceStack adds Auto Querying functionality akin to OData’s querying support for Web Api, although we’ve disregarded their approach which we’ve long considered promotes web service anti-patterns.

  1. Should i use AutoQuery? Does SS suggest use AutoQuery?
  2. Is [Route(“/cities/{city}/kindergartens”, “GET”)] not good? I think city and it’s builds has a tree structure.
  3. if i want to query by fields, can i use [Route(“/kindergartens/{fields1}/{fields2}/{fields3}”, “GET”)], is it good?
  4. if i want to query by fields, can i use [Route("/kindergartens/], and add a list to my DTO to filter url like this /movies?ratings=G,PG-13, am i right? Is it good?

AutoQuery provides an easy to use API for querying data you (may be) already are accessing via OrmLite and the routes it exposes, like in the example (/movies?ratings=G,PG) are concise and easy to understand.

I don’t know the rest of the structure in your application so I can’t be sure. If you already have other routes relating to cities and simply want to provide kindergartens off that route it makes sense.

What if you want to query by field1 and field3 but not field2? It would be better if these were passed by query string where the order doesn’t matter. This can be done using SS and default routes any way. AutoQuery just does a lot of this work for you.

I’m not exactly sure what you mean here. You can also have custom query service if you need more control on how the search works.

Thank you, I will try AutoQuery.

if i want to query by fields, can i use [Route("/kindergartens/], and add a list to my DTO to filter url like this /movies?ratings=G,PG-13, am i right? Is it good? I give a example below. I think AutoQuery is better than this

[Route(“/dogs”)]
public class SearchDogs {
public List Fields { get; set; }
}
Which will let you call it with:

/dogs?fields=name,color,location

The example with movies shows Ratings property, which is added to the request object to be an array. Eg, the requester can specify multiple ratings that they are interested in. The ‘Rating’ field is just a string as Movies only have 1 rating.

I’m not sure what you are trying to achieve with this example.

If you have a request object for finding dogs by location, you might be interested in multiple location names. Eg, a dog has 1 location, but the requester is interested in dogs from multiple locations so it would be:

[Route("/dogs")]
public class SearchDogs : QueryBase<Dog>
{
    public string[] Locations { get;set; }
}

public class Dog
{
    [AutoIncrement]
    public int Id { get;set; }        

    public string Location { get;set; }
}

You could then make the request /dogs?Locations=WA,SA where WA and SA are locations that dogs have.