Xamarin forms Rest Client [closed] - rest

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
Improve this question
Anybody suggest me a good Rest client that i can use for my xamarin forms cross platform application ?
(Android and Windows Phone)
Thanks in advance.

That's a very open question.
Anyway my favorite:
Refit
Updated Removing the other two libraries that even though you can do REST with them they are not considered REST clients but HTTP clients.

You can you Microsoft HTTP Client Libraries.
Then, you define a RestService class that contains a HttpClient instance:
public class RestService : IRestService
{
HttpClient client;
public RestService()
{
client = new HttpClient();
client.MaxResponseContentBufferSize = 256000;
}
// example for GET request
public async Task<List<TodoItem>> RefreshDataAsync()
{
var uri = new Uri(string.Format(Constants.RestUrl, string.Empty));
var response = await client.GetAsync(uri); // make a GET request
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
// handle response here
}
}
}
You should follow this article:
https://developer.xamarin.com/guides/xamarin-forms/cloud-services/consuming/rest/

I do not know if there are simple implementation for this purpose but you have to write your own parsers, senders, receivers according to your needs. I would give you a little example :) First of all i have a base class for my generic restCall
public abstract class BaseDto
{
public string Id {get;set;}
}
than write your business objects like
public class UserDto : BaseDto
{
public string Name {get;set;}
//etc.
}
public class SavedUserDto : BaseDto
{
public int Id {get;set;}
public string Name {get;set;}
//etc.
}
than write a simple http caller
public string Post<T>(string url, T entity) where T : BaseDto
{
//here u will write a HttpClient and send receive json. U can find examples on the net. Of course use Newtonsoft for json convertions
}
Than write a generic method to call this post method, of course you will send a baseDto and receive a baseDto too :)
public K Call<T, K>(
string restApiPath,
T entity) where T : BaseDto where K : BaseDto
{
var response = Post(restApiPath, entity);
//you can handle errors, auth faults etc. here.
return JsonConvert.DeserializeObject<K>(response);
}
than in your code just do
var savedUser = Call<UserDto,SavedUserDto>("127.0.0.1/user/save",new UserDto{Name="John"})
Hope it can give you an idea. Than when you add a new service method on your rest api, you can call it just with a single line of code (of course you have to write new business DTO's - aka data transfer objects:))
Of course all this POST and CALL methods on different classes. Do not forget, a class must do only one thing. So POST method owner class (let's call it HttpCaller) will only send the Dto to the server and get the answer. CALL method owner class (lets call it MyService) will get the resut and process it etc.

You can use HttpClient. It is good. get from nuget System.Http.Net

Related

Spring Boot REST API Endpoint Mapping best practice

I am using below endPoint URL Mapping with HTTP Methods like ( POST, DELETE, GET, PUT)
POST for Create a new Trade -
#PostMapping("/trade")
DELETE for Delete a Trade with specific id -
#DeleteMapping("/trade/{id}")
GET for Get details of specific Trade -
#GetMapping("/trade/{id}")
PUT for Update Trade details -
#PutMapping(“/trade/{id}”)
GET for Retrieve all Trade list of the collection -
#GetMapping("/trades")
Spring currently supports five types of inbuilt annotations for handling different types of incoming HTTP request methods which are GET, POST, PUT, DELETE and PATCH. These annotations are:
#GetMapping
#PostMapping
#PutMapping
#DeleteMapping
#PatchMapping
From the naming convention, we can see that each annotation is meant to handle the respective incoming request method types, i.e. #GetMapping is used to handle GET type of request method, #PostMapping is used to handle POST type of request method, etc.
if I am missing anything here Please suggest
Add API version like
#RestController
#RequestMapping("/API/V1")
public class TestController {
#RequestMapping("/greeting")
public String greeting( {
return "welcome";
}
}
For versioning there are several approaches you can use:
URI path:
Include the version number in the URL path of the endpoint.
For example v1 in /api/v1/trade:
public class TradeController {
#GetMapping("v1/trade")
public Trade tradeVersionOne() {
return new Trade("123","Trade Result");
}
#GetMapping("v2/trade")
public Trade tradeVersionTwo() {
return new Trade(new RealTimeTrade("123", "Real Time Trade Result"));
}
}
Query parameters:
Pass the version number as a query parameter with a specified name.
For example: ?version=1 in /api/trade?version=1:
public class TradeController {
#GetMapping(name = "v1/trade", params = "version=1")
public Trade tradeVersionOne() {
return new Trade("123","Trade Result");
}
#GetMapping(name = "v2/trade", params = "version=2")
public Trade tradeVersionTwo() {
return new Trade(new RealTimeTrade("123", "Real Time Trade Result"));
}
}
Custom HTTP headers:
Define a new header that contains the version number in the request.
Content negotiation:
Include the version number in the Accept header along with the accepted content type.

Unit tests for simple REST client [duplicate]

This question already has answers here:
Need some advice for trying to mock a .NET WebClient or equivalent
(2 answers)
Closed 6 years ago.
Let's assumed that i've got simple method which gets some data from REST service. Method looks like:
public string GetDataFromRest(string uri) {
string result = String.Empty;
using(WebClient web = new WebClient()) {
result = web.DownloadString(uri);
}
return result;
}
So, now i want to create unit test for this method. I don't want to use external REST service but i want fake response from any URI without real conecting to service. Something like every execute of GetDataFromRest(uri) in Unit Test -> always returns some XML.
As the posted answer goes into some detail, part of your problem is you have a dependency on the WebClient class.
A sample wrapper for WebClient could look like:
public interface IWebClient
{
string DownloadString(string address);
}
public class WebClientWrapper : IWebClient
{
public string DownloadString(string address)
{
using(WebClient web = new WebClient()) {
return result = web.DownloadString(uri);
}
}
}
public class MyClass
{
private readonly IWebClient _webClient;
public MyClass(IWebClient webClient)
{
_webClient = webClient;
}
public string GetDataFromRest(string uri)
{
return _webClient.DownloadString(uri);
}
}
Now of course going this route means WebClientWrapper can be unit tested with a "less real" URI or what that you specifically control. I've only implemented one method of the WebClient, but this externalizes the dependency within GetDataFromRest from a real URI, as you can now mock the return data. This also helps in that anything else you need a WebClient for, you can now use the wrapper class, and easily mock the returned data, as you are now programming to an interface, rather than a concretion.

Restful API and SpringMVC, should I make path variables as #RequestBody object's fields for convenience?

I own an application for collecting feedback.
The api looks like this:
POST /customer/feedback/{feedbackId} HTTP/1.1
Host: localhost:9999
Content-Type: application/json
Content-Body: {'qaSays':'Approved', 'qaRating':98}
//This results the feedback (find by feedbackId) gets updated
The application is built using spring-mvc
//in controller
#RequestMapping(value="/customer/feedback/{feedbackId}")
#ResponseStatus(OK)
public void handle(#PathVariable("feedbackId") feedbackId,
#RequestBody ApproveFeedbackCommand command) {
command.setFeedbackId(feedbackId);
commandGateway.send(command);
}
//Command
public class ApproveFeedbackCommand {
private String feedbackId;//makes no sense for client
private String qaSays;
private int qaRating;
}
The solution above works, but I have a feeling that something goes wrong here.
The question is:
1.Should I use ApproveFeedbackCommand as #RequestBody just for convenience?
The extra field "feedbackId" may confuse the other developer, and it is annoying to set path variables manually.
2.Should I add an ApproveFeedbackBody(exclude "feedbackId") for separate concerns?
But this seems to add some duplicate code and some manual command parameter extraction.
#RequestMapping(value="/customer/feedback/{feedbackId}")
#ResponseStatus(OK)
public void handle(#PathVariable("feedbackId") id,
#RequestBody ApproveFeedbackBody body) {
ApproveFeedbackCommand command = convert(id, body);//manual convert here
commandGateway.send(command);
}

Using EF and WebAPI, how can I return a ViewModel AND support IQueryable/OData? [duplicate]

This question already has answers here:
Web API Queryable - how to apply AutoMapper?
(3 answers)
Closed 9 years ago.
I've got an ASP.NET WebAPI project. I've recently created EntityFramework entities for all my data tables. But I don't want to expose my data layer & schema to my users. How can I map my entities to a ViewModel (automapper?) and provide IQueryable return type so that my API supports OData?
OData supports query composition and SQL-like parameters. I guess I'd need to provide some kind of 2-way translation for the query-composition part? Does that mean a custom LINQ provider? I hope it's easier than that.
Or should I give up on IQueryable/OData?
I found the answer here: Web API Queryable - how to apply AutoMapper?
Instead of using [Queryable] you can use a parameter of type ODataQueryOptions<T> to apply OData operations against any type or LINQ query you wish. Here's a great example that doesn't even need to use AutoMapper:
public virtual IQueryable<PersonDto> Get(ODataQueryOptions<Person> odataQuery){
odataQuery.Validate(new ODataValidationSettings(){
AllowedFunctions = AllowedFunctions.AllMathFunctions
});
var people = odataQuery.ApplyTo(uow.Person().GetAll());
return ConvertToDtos(people);
}
Here's the Microsoft page explaining the specifics of this usage. (about half way down)
I was able to successfully test this using a ViewModel class.
public class InvoiceViewModel
{
public int InvoiceID { get; set; }
public string InvoiceNumber { get; set; }
}
in the Get, select from your entity into your viewmodel:
public override IQueryable<InvoiceViewModel> Get()
{
var ctx = new CreditPointEntities();
return ctx.Invoices.Select(i => new InvoiceViewModel
{
InvoiceID = i.InvoiceID,
InvoiceNumber = i.InvoiceNumber
}).AsQueryable();
}
Make sure you use the viewmodel in your modelbuilder line in webapiconfig.cs
modelBuilder.EntitySet<InvoiceViewModel>("Invoice");
with this, you can use a url like
http://website/odata/Invoice?$filter=InvoiceID eq 1
I confirmed through sql profiler that the filter was being passed through to SQL.
if you are using Automapper, you could use projections in it. Example:
public class ProductsController : EntitySetController<Product, int>
{
private DbProductsContext _db = new DbProductsContext();
public override IQueryable<ProductDto> Get()
{
return _db.Products.Project().To<ProductDto>();
}
...

Custom Logic and Proxy Classes in ADO.NET Data Services

I've just read "Injecting Custom Logic in ADO.NET Data Services" and my next question is, How do you get your [WebGet] method to show up in the client-side proxy classes? Sure, I can call this directly (RESTfully) with, say, WebClient but I thought the strong typing features in ADO.NET Data Services would "hide" this from me auto-magically.
So here we have:
public class MyService : DataService<MyDataSource>
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(IDataServiceConfiguration config)
{
config.SetEntitySetAccessRule("Customers", EntitySetRights.AllRead);
config.SetServiceOperationAccessRule("CustomersInCity", ServiceOperationRights.All);
}
[WebGet]
public IQueryable<MyDataSource.Customers> CustomersInCity(string city)
{
return from c in this.CurrentDataSource.Customers
where c.City == city
select c;
}
}
How can I get CustomersInCity() to show up in my client-side class defintions?
When you see your Odata in browser, you will see link ...
e.g. http://localhost:1234/odataService.svc
just write your method name after the link
for your method it will be something like this...
http://localhost:1234/odataService.svc/CustomersInCity?city="London"