Wikipedia: "Representational state transfer (REST) is a style of software architecture for distributed hypermedia systems such as the World Wide Web."
Represenational State Transfer (Roy Felding): "REST is a coordinated set of architectural constraints that attempts to minimize latency and network communication, while at the same time maximizing the independence and scalability of component implementations."
- Client-Server - data stays on server
- Stateless
- no client context on the server
- don't set 'current' anything
- Cacheable
- Layered system
- Code on demand
- Uniform Interface (through URIs)
- Client uses URI to request a representation of a resource
- The exact resource is indicated by the URI itself, not the request body
- If you are building a REST service, your URLs are your user interface.
- Good
GET /tasks/1
POST /projects/1/tasks
- Bad
POST /getTask/
GET /addTask?title=5
- POST (create)
- 201 (Created)
- 422 (Unprocessable Entity)
- GET, PUT, DELETE, PATCH
- 200 (OK)
- 404 (NOT FOUND)
- Todos application
- Manage tasks
get '/tasks' do
Task.to_json
end
post '/tasks' do
pp @data
@task = Task.new @data
if @task.valid?
@task.save
@task.to_json
else
status 422
@task.errors_hash.to_json
end
end
get '/tasks/:id' do
@task = Task.find(params)
raise Sinatra::NotFound unless @task
@task.to_json
end
put '/tasks/:id' do
@task = Task.find :id => params[:id]
raise Sinatra::NotFound unless @task
@task.update @data
@task.to_json
end
delete '/tasks/:id' do
@task = Task.find :id => params[:id]
raise Sinatra::NotFound unless @task
@task.destroy
@task.to_json
end
-(void)createObject:(NSObject *)theObject withMapping:(RKObjectMapping *)mapping{
self.target = theObject;
[[LBDataManager sharedManager].rkObjectManager
postObject:theObject mapResponseWith:mapping delegate:self];
}
-(void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error{
[self.delegate objectDidFailCreation:error];
[super objectLoader:objectLoader didFailWithError:error];
}
-(void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)loadedObjects{
[self.delegate didCreateObject:[loadedObjects objectAtIndex:0]];
[super objectLoader:objectLoader didLoadObjects:loadedObjects];
}
-(void)saveTask{
[[LBCreateObjectService serviceWithDelegate:self]
createObject:self.task
withMapping:[Task serializationMapping]];
}
-(void)didCreateObject:(NSObject *)theObject{
[self.delegate taskFormView:self didSaveTask:self.task];
}
-(void)objectDidFailCreation:(NSError *)error{
[[[UIAlertView alloc] initWithTitle:@"Error"
message:error.localizedDescription
delegate:self
cancelButtonTitle:@"Ok"
otherButtonTitles: nil] show];
}
-(void)loadData{
[[LBReadObjectService serviceWithDelegate:self] readObjectsForMapping:[Task mapping] atPath:@"tasks"];
}
-(void)readObjectService:(LBReadObjectService *)service didReadObjects:(NSArray *)objects{
self.tasks = objects;
[self.tableView reloadData];
}
-(void)updateTask{
[[LBUpdateObjectService serviceWithDelegate:self]
updateObject:self.task
withMapping:[Task serializationMapping]];
}
-(void)didUpdateObject:(NSObject *)target{
[self.delegate taskFormView:self didSaveTask:self.task];
}
-(void)deleteTask{
[[LBDeleteObjectService serviceWithDelegate:self] deleteObject:self.task];
}
-(void)didDeleteObject:(NSObject *)target{
[self.navigationController popViewControllerAnimated:YES];
}
Handling relationships