Skip to main content

Implementing UPDATE operation

Previously, we created and read blog posts. Now, let's implement and make a call to update a blog post. We'll also learn how to handle an exception with a custom exception handler.

What you need​

You need to have the following files obtained from previous steps. You can always download the full version, instead of creating one yourself.

1. Implement server-side​

Let's implement the server-side for updating blog posts. This time, we'll use a custom exception handler.

Add an exception handler​

First, add a custom exception handler for the blog service.

  1. Add an exception handler class to convert an IllegalArgumentException into a BlogNotFoundException.
BlogServiceExceptionHandler.java
package example.armeria.server.blog.thrift;

import java.util.function.BiFunction;

import com.linecorp.armeria.common.RpcResponse;
import com.linecorp.armeria.server.ServiceRequestContext;

import example.armeria.blog.thrift.BlogNotFoundException;

public class BlogServiceExceptionHandler implements BiFunction<ServiceRequestContext, Throwable, RpcResponse> {

@Override
public RpcResponse apply(ServiceRequestContext serviceRequestContext, Throwable cause) {
if (cause instanceof IllegalArgumentException) {
return RpcResponse.ofFailure(new BlogNotFoundException(cause.getMessage()));
}
return RpcResponse.ofFailure(cause);
}
}
  1. In the Main class, bind the BlogServiceExceptionHandler to our service.
Main.java
...
private static Server newServer(int port) throws Exception {
final THttpService tHttpService =
THttpService.builder()
.addService(new BlogServiceImpl())
.exceptionHandler(new BlogServiceExceptionHandler()) // Add this
.build();
...
}

Implement the service method​

In the BlogServiceImpl class, implement the updateBlogPost() method to update a blog post. This time, let's use the IllegalArgumentException instead of the BlogNotFoundException.

BlogServiceImpl.java
@Override
public void updateBlogPost(UpdateBlogPostRequest request, AsyncMethodCallback<BlogPost> resultHandler)
throws TException {
final BlogPost oldBlogPost = blogPosts.get(request.getId());
if (oldBlogPost == null) {
resultHandler.onError(
new IllegalArgumentException("The blog post does not exist. ID: " + request.getId()));
} else {
final BlogPost newBlogPost = oldBlogPost
.deepCopy()
.setTitle(request.getTitle())
.setContent(request.getContent())
.setModifiedAt(Instant.now().toEpochMilli());
blogPosts.put(request.getId(), newBlogPost);
resultHandler.onComplete(newBlogPost);
}
}

2. Implement client-side​

Add a method updateBlogPost() to send a request to update a blog post.

BlogClient.java
import example.armeria.blog.thrift.UpdateBlogPostRequest;
...
BlogPost updateBlogPost(int id, String newTitle, String newContent) throws TException {
final UpdateBlogPostRequest request = new UpdateBlogPostRequest().setId(id).setTitle(newTitle).setContent(newContent);
return blogService.updateBlogPost(request);
}

3. Test updating a blog post​

Let's try updating the content of the first blog post. Add a method like the following.

BlogServiceTest.java
@Test
@Order(5)
void updateBlogPosts() throws TException {
final BlogClient client = new BlogClient(server.httpUri(), "/thrift");
final BlogPost updated = client.updateBlogPost(0, "My first blog", "Hello awesome Armeria!");
assertThat(updated.getId()).isZero();
assertThat(updated.getTitle()).isEqualTo("My first blog");
assertThat(updated.getContent()).isEqualTo("Hello awesome Armeria!");
}

Run all the test cases on your IDE or using Gradle. Check that you see the test is passed.

4. Test an error case​

To check that our exception handler is working, let's try updating a post which does not exist.

  1. Bind the exception handler to the service for the test server.
BlogServiceTest.java
@RegisterExtension
static final ServerExtension server = new ServerExtension() {
@Override
protected void configure(ServerBuilder sb) throws Exception {
sb.service("/thrift", THttpService.builder()
.exceptionHandler(new BlogServiceExceptionHandler()) // Add this
.addService(new BlogServiceImpl())
.build());
}
};
  1. Add a test method to update a blog post with an invalid ID, asserting a BlogNotFoundException is thrown.
BlogServiceTest.java
@Test
@Order(6)
void updateInvalidBlogPost() {
final BlogClient client = new BlogClient(server.httpUri(), "/thrift");
final Throwable exception = catchThrowable(() -> {
final BlogPost updated = client.updateBlogPost(Integer.MAX_VALUE, "My first blog", "Hello awesome Armeria!");
});
assertThat(exception)
.isInstanceOf(BlogNotFoundException.class)
.extracting("reason")
.asString()
.isEqualTo("The blog post does not exist. ID: " + Integer.MAX_VALUE);
}
  1. Run all the test cases on your IDE or using Gradle. Check that you see the test is passed.

What's next​

In this step, we've implemented a service method and client method for updating a blog post. We've also added an exception handler.

Next, at Step 6. Implement DELETE, we'll implement a method for deleting a blog post and add a Documentation Service to our service.

Like Armeria?
Star us ⭐️

×