Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
public Something Put(string first, string second)
[FromBody], но она может быть применена только к одному параметру. И придется определять модели для каждого чиха.public string Get(int first)
{
return "hello";
}
public string Get(int first, bool other)
{
return "word";
}
POST /orders/
<order>
<name>Sample Order</name>
</order>
POST /orders/1111/items
<order-item>
<name>Item 1</name>
</order-item>
GET /orders/
<order-collection>
<orders>
<order>
<name>AAA</name>
</order>
</orders>
</order-collection>
POST /orders/paid
<paid-order>
<order href="http://sample.com/orders/1" />
</paid-order>
Оплатить заказ?
POST /orders/paid
<paid-order> <order href="http://sample.com/orders/1" /> </paid-order>
<paid-order>
<order-ref>1<order-ref/>
</paid-order>
public class ResourceLink
{
public string Rel { get; set; }
public string Href { get; set; }
}
public class ResourceBase
{
public ResourceLink[] Links { get; set; }
}
public class Invoice : ResourceBase
{
public decimal GrandTotal { get; set; }
}
public class InvoicePayment : ResourceBase
{
}
Invoice -> http://foo.com/rel/invoice
InvoicePayment -> http://foo.com/rel/invoice-payment
POST /invoices/
<Invoice>
<GrandTotal>10.00</GrandTotal>
</Invoice>
POST /payments/
<InvoicePayment>
<Links>
<Link rel="http://foo.com/rel/invoice" href="http://bar.com/invoices/12345" />
</Links>
</InvoicePayment>
var ctx = new DataContext();
var invoice = ctx.Invoices.Where(x=>x.Id==54123).FirstOrDefault();
ctx.Invoices.Delete(invoice); // не помню, может быть функция как-то по-другому называется.
ctx.SaveChanges();
<Invoice>
<Links>
<Link rel="self" href="http://foo.com/invoices/12345" />
</Links>
<GrandTotal>10.00</GrandTotal>
</Invoice>
POST /invoices/
<Invoice>
<GrandTotal>10.00</GrandTotal>
</Invoice>
<Invoice>
<Links>
<Link rel="self" href="http://bar.com/invoices/12345" />
</Links>
<GrandTotal>10.00</GrandTotal>
</Invoice>
POST /payments/
<InvoicePayment>
<Links>
<Link rel="http://foo.com/rel/invoice" href="http://bar.com/invoices/12345" />
</Links>
</InvoicePayment>
<InvoicePayment>
<Links>
<Link rel="self" href="http://bar.com/payments/12345" />
<Link rel="http://foo.com/rel/invoice" href="http://bar.com/invoices/12345" />
</Links>
<Created>01/09/12 10:00AM</Created>
</InvoicePayment>
public void Post(Payment payment)
{
var invoiceLink = payment.Links.Single(x=>x.Rel=="http://foo.com/rel/invoice");
var invoiceData = RouteTable.Routes.GetRouteData(invoiceLink.Href); // в WebApi будет чуть-чуть отличаться
}
public class InvoiceController : ApiController
{
public Invoice Get(int invoiceId)
{
// тут реализация
}
}
GET /orders
<order-collection>
<links>
<link rel="self" href="http://bar.com/orders" />
</links>
<orders>
<order-preview>
<links>
<link rel="http://foo/order" href="http://bar.com/orders/1" />
</links>
</order-preview>
<order-preview>
<links>
<link rel="http://foo/order" href="http://bar.com/orders/2" />
</links>
</order-preview>
<orderts>
</order-collection>
GET http://bar.com/orders/2
<order>
<links>
<link rel="self" href="http://bar.com/orders/2" />
</links>
<name>AAAA</name>
<created>BBBB</created>
</order>
Ок, где лежит объект с идентификатором 12345678? Как мне его получить?
Вряд ли вы сможете ответить на этот вопрос, а вот где лежит объект с идентификатором
foo.com/users/12345678
Как его получить?
Думаю, ответ на второй вопрос будет куда проще и понятнее.
<order>
<links>
<link rel="self" href="http://bar.com/orders/1234" />
<link rel="http://foo/orderitem" href="http://bar.com/orders/1234/item/1" />
<link rel="http://foo/orderitem" href="http://bar.com/orders/1234/item/2" />
<link rel="http://foo/orderitem" href="http://bar.com/orders/1234/item/3" />
</links>
<name>AAAA</name>
<created>BBBB</created>
</order>
<order>
<links>
<link rel="self" href="http://bar.com/orders/1234" />
</links>
<name>AAAA</name>
<created>BBBB</created>
<items>
<item ... />
<item ... />
<item ... />
</items>
</order>
int[] GetItemsIdentificators()
Item[] GetItems()
GET /users/1
<user>
<name> Usr 01 </name>
<groups>
<group>
<links>
<link rel="foo/group" href="bar/groups/1" />
</links>
<name>Group 1</name>
</group>
</groups>
</user>
POST /users/
<user>
<name> Usr 01 </name>
<groups>
<group>
<links>
<link rel="foo/group" href="bar/groups/1" />
</links>
</group>
</groups>
</user>
<user>
<name> Usr 01 </name>
<groups>
<group>
<name>New Group for Usr 01</name>
</group>
</groups>
</user>
<user>
<links>
<link rel="self" href="bar.com/users/1" />
<link rel="foo/user-groups" href="bar.com/users/1/groups" />
</links>
<name>User 01</name>
</user>
POST bar.com/users/1/groups
Обе функции работают и часто встречаются, но давай-те подумаем, что получение идентификаторов скорее связано с необходимостью создать более сложный объект, который и будет ссылаться на эти самые идентификаторы.
var link = data.Links
.Where(function(x) { return x.rel=="http://foo.com/rel/invoice"; })
.Select(function(x) { return x.Href; })
.FirstOrDefault();
$.ajax({ url: link }).done(function(data) { console.log(data); });
<user>
<links>
<link rel="self" href="bar.com/users/1" />
<link rel="foo/user-groups" href="bar.com/users/1/groups" />
</links>
<name>User 01</name>
</user>
<link rel="foo/user-groups" href="bar.com/users/1/groups" />
А я говорю об API на безе REST которым может пользоваться пару сонет не известных и не подконтрольных вам продуктов
<user>
<id href="http://a.users.foo.com/users/1" />
<container href="http://users.bar.com/users/" />
</user>
public interface IDependencyResolver
{
object GetService(Type serviceType);
IEnumerable<object> GetServices(Type serviceType);
}
public interface IDependencyScope : IDisposable
{
object GetService(Type serviceType);
IEnumerable<object> GetServices(Type serviceType);
}
public interface IDependencyResolver : IDependencyScope, IDisposable
{
IDependencyScope BeginScope();
}
public class ResourceQuery
{
public string Param1 { get; set; }
public int OptionalParam2 { get; set; }
}
public class SampleResourceController : ApiController
{
public SampleResourceModel Get([FromUri] ResourceQuery query)
{
// и тут уж как вам больше нравится: ModelBinder, или самим писать проверки
if(!ModelState.IsValid)
{
throw new HttpResponseException(HttpStatusCode.BadRequest);
}
}
}
разграничение прав доступа к данным
ограничивание запросов по причине перформанса/тротлинга
public IQueryable<History> History()
{
var currentRole = currentUser.GetCurrentRole();
switch (currentRole)
{
case Role.A:
return context.Histories.AsQueryable();
break;
case Role.B:
return context.Histories.Skip(1000);
break;
case Role.C:
return context.Histories.Take(10);
break;
}
}
SELECT
[Limit1].[Id] AS [Id],
[Limit1].[Name] AS [Name]
FROM ( SELECT TOP (10) [c].[Id] AS [Id], [c].[Name] AS [Name], row_number() OVER (ORDER BY [c].[Id] ASC) AS [row_number]
FROM [dbo].[Models] AS [c]
) AS [Limit1]
WHERE [Limit1].[row_number] > 1000
ORDER BY [Limit1].[Id] ASC
RESTFul Api контроллеры в .NET MVC 4