0

I have 2 question :

1.what is best practice for REST API method GET if there are many condition with the parameters.

example :

i have customers API and the user wants the api with request parameter like these :

  • idnumber and mobilephone

  • name (can use contains if user input %) or mobilephone

  • idnumber and idtype or date of birth

should i make 3 custom api with the same route for each commbination of parameters?

i ve searched everywhere but i cant find the answer, most article only share common best practice like these :

  • api/customer -- get all customer

  • api/customer/{id} -- get customer by id

2.Regarding the response api

example :

I have customers API and the response is like this : - CustomerID - CustomerName - IDNumber - MobilePhone - Address

lets say i have 2 user that consume this API but i only want 1 user can see response with "mobilephone" and "address" but another user only customrid,customername and idnumber , the question is how can i make the api?should i create 2 api?

sorry for my bad english

i googled everywhere but i cant find the right answwer please help

William
  • 11
  • 1
  • I am not quite savvy but have used IQueryable to use filtering on different inputs. [Check this out](https://stackoverflow.com/questions/1578778/using-iqueryable-with-linq/1578977). – Jawad Jan 27 '20 at 03:16
  • its not about filtering data, but how i design the api with different kind of parameter and condition – William Jan 27 '20 at 04:09

4 Answers4

0

Let me attempt to answer these.

A typical way would be to still just create an api like api/customer. What you should expect from the user/application consuming the API is to pass in a Customer object(not in the literal OOP sense). Something like a json object

{
 idnumber: "123",
 mobilephone: "",
 DOB: null
}

Something like this: https://weblog.west-wind.com/posts/2013/dec/13/accepting-raw-request-body-content-with-aspnet-web-api

  1. When processing this object you can probably check the type of the user in the code. Is it a super-user or regular user(just an example). Based on this you can return an appropriate response.

I hope I understood your question correctly.

Vaibhav
  • 47
  • 1
  • 6
0

Regarding your first question, please try to make api calls distinct as possible. 1. For the above given example, you should ideally use three different methods as the validation logic will be different in each case. 2. Also, looking at scalability and maintainability, it will be real task to handle simple change without affecting the other two.

For your second query, you can integrate both the calls in a single method. Since the underlying model is same, generate a generic response and filter out the results accordingly. Or else, create a wrapper on model to generate customized response as per user. But no need to expose two api calls for this.

Swanand Pangam
  • 858
  • 1
  • 10
  • 25
  • hi swan, for point 1. youre saying that i should create 1 api and put the validation logic inside it?is it best practice to do that?and at some point the parameter rule will collide with other parameter if someday im gonna add the same parameter with different rule. point 2.the user is not included in the parameters because i m using api management (credential and user managed by this api management) – William Jan 27 '20 at 09:40
  • For point 1, I am saying to use multiple api calls. As maintaining validation logic in one api will be difficult and quite messy. For point 2, a single call will help you maintain all validation and model logic in through single api call. – Swanand Pangam Jan 27 '20 at 10:31
0
  1. always create different endpoint for each web api calls. if the parameters that sent are a different types for each scenario then you may be able to overload the conntroller method with the same name.

  2. this is definitely requires two different endpoints, because the response model is different. this way you don't make alot of boxing and unboxing for the response datamodel.

gadasadox
  • 109
  • 1
  • 9
-1
[![class Program
    {
        static void Main(string\[\] args)
        {
            var customer = new Customer() { CustomerID = 666, CustomerName = "john", IDNumber = "john123", MobilePhone = "9834567899", Address = "Test address 1" };

            //For user 1
            var allewdProperties = new string\[\] { "CustomerName", "IDNumber", "CustomerID" };//For user 1


            var json = JsonConvert.SerializeObject(customer
                            ,
                            new JsonSerializerSettings() { ContractResolver = new CustomContractResolver(allewdProperties.ToList()) }
                        );

            //Data for user1
            Console.WriteLine("Data for user 1");
            Console.WriteLine(json);

            //for user 2
            allewdProperties = new string\[\] { "MobilePhone", "Address" };//For user 2
            json = JsonConvert.SerializeObject(customer,
                new JsonSerializerSettings() { ContractResolver = new CustomContractResolver(allewdProperties.ToList()) }
            );
            Console.WriteLine("Data for user 2");
            Console.WriteLine(json);

            Console.ReadLine();
        }
    }

    public class Customer
    {
        public int CustomerID { set; get; }
        public string CustomerName { set; get; }
        public string IDNumber { set; get; }
        public string MobilePhone { set; get; }
        public string Address { set; get; }
    }

    public class CustomContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
    {
        IEnumerable<string> _allowedProps = null;

        public CustomContractResolver(IEnumerable<string> allowedProps)
        {
            _allowedProps = allowedProps;
        }

        protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
        {
            return _allowedProps.Select(p => new JsonProperty()
            {
                PropertyName = p,
                PropertyType = type.GetProperty(p).PropertyType,
                Readable = true,
                Writable = true,
                ValueProvider = base.CreateMemberValueProvider(type.GetMember(p).First())
            }).ToList();
        }
    }][1]][1]