Better way to REST Julije Kostov Rest Architectural
Better way to REST Julije Kostov
Rest Architectural constraints: ● ● ● Client-server Stateless server Caching Uniform interface Layered system Code on demand
RESTful Web services ● HTTP protocol ● URL ● HTTP GET, POST, PUT and DELETE methods ● ● ● GET /items/{id} POST /items PUT /items/{id} DELETE /items/{id}
Strengths and weaknesses Strengths: ● Easy integration ● Small communication overhead ● Auth and Rate limit definition ● Good tools Weaknesses: ● ● Use-case definition Server defined data Boilerplate code User defined REST
Swagger ● ● API Standardization API Description Discovery metadata Client and server code generator
Graph. QL API query language and server-side runtime for executing queries
Graph. QL objects
Schema
Schema example schema { query: Star. Wars. Query mutation: Star. Wars. Mutation } public class Star. Wars. Schema : Schema { public Star. Wars. Schema(IService. Provider provider) : base(provider) { Query = provider. Get. Required. Service<Star. Wars. Query>(); Mutation = provider. Get. Required. Service<Star. Wars. Mutation>(); } }
Query type Star. Wars. Query { hero(): Droid human(id: String): Human droid(id: String): Droid } public class Star. Wars. Query : Object. Graph. Type<object> { public Star. Wars. Query(Star. Wars. Data data) { Name = "Query"; Field<Droid. Type>("hero", resolve: context => data. Get. Droid. By. Id. Async("3")); Field<Human. Type>( "human", arguments: new Query. Arguments( new Query. Argument<Non. Null. Graph. Type<String. Graph. Type>> { Name = "id" } ), resolve: context => data. Get. Human. By. Id. Async(context. Get. Argument<string>("id")) ); Func<Resolve. Field. Context, string, object> func = (context, id) => data. Get. Droid. By. Id. Async(id); Field. Delegate<Droid. Type>( "droid", arguments: new Query. Arguments( new Query. Argument<Non. Null. Graph. Type<String. Graph. Type>> { Name = "id" } ), resolve: func ); } }
Mutation public class Star. Wars. Mutation : Object. Graph. Type { public Star. Wars. Mutation(Star. Wars. Data data) { Name = "Mutation"; Field<Human. Type>( "create. Human", arguments: new Query. Arguments( new Query. Argument<Non. Null. Graph. Type<Human. Input. Type>> {Name = "human"} ), resolve: context => { var human = context. Get. Argument<Human>("human"); return data. Add. Human(human); }); type Star. Wars. Mutation { create. Human($human: Human. Input. Type): Human } } }
Example
Client query { hero { name } droid(id: "3") { name } } "data": { "hero": { "name": "R 2 -D 2" }, "droid": { "name": "R 2 -D 2" } } }
Client mutation ($human: Human. Input. Type!) { create. Human(human: $human) { id name } } "variables": { "human": { "name": "Boba Fett" } } { "data": { "create. Human": { "id": 5, "name": "Boba Fett" } } }
Strengths and weaknesses Strengths: ● Combine multiple data sources ● Data on demand ● API metadata ● Strong types Weaknesses: ● ● Auth and rate limit Caching Data graph organization Performance (n + 1)
API example
Where to use ● ● Multiple clients Multiple data sources Microservices Limited bandwidth
OData protocol A set of practices for building and consuming RESTful APIs
Odata specifications ● Standardization of URL conventions, HTTP methods and status codes ● Defined Request/Response schemas ● Filtering, ordering, paging, joining and aggregations ● Resource metadata ● Easy setup ● You can focus on business logic
Request example odata/Segment. Requirements ? $count=true &$top=10 &$skip=50 &$filter=Equipment. Requirements/any(e: e/Equipment/Name eq 'Eq. Name') &$expand=Process. Segment($expand=Location), Personnel. Requirem ent, Equipment. Requirement($expand=Equipment)
Thanks : )
- Slides: 21