Skip to main content

Implementing CREATE operation

In the previous step, we defined empty service methods. In this step, we'll fill in one of the service methods to create a blog post and implement a corresponding client method. Also, we'll try making a call to the service method with test code using Armeria's ServerExtension.

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 a service method to create a blog post.

  1. In the BlogServiceImpl class, create an ID generator to issue temporary blog post IDs and a map to contain blog posts.
BlogServiceImpl.java
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

public class BlogServiceImpl implements BlogService.AsyncIface {
private final AtomicInteger idGenerator = new AtomicInteger();
private final Map<Integer, BlogPost> blogPosts = new ConcurrentHashMap<>();
...
}
  1. In the createBlogPost() method, create a BlogPost object with a generated ID and request parameters.
BlogServiceImpl.java
import java.time.Instant;
...
@Override
public void createBlogPost(CreateBlogPostRequest request, AsyncMethodCallback<BlogPost> resultHandler)
throws TException {
final int id = idGenerator.getAndIncrement();
final Instant now = Instant.now();
final BlogPost blogPost = new BlogPost()
.setId(id)
.setTitle(request.getTitle())
.setContent(request.getContent())
.setModifiedAt(now.toEpochMilli())
.setCreatedAt(now.toEpochMilli());
}
  1. In the createBlogPost() method, save the post information in the blogPosts map and return the information of the created blog post to the resultHandler.
BlogServiceImpl.java
@Override
public void createBlogPost(CreateBlogPostRequest request, AsyncMethodCallback<BlogPost> resultHandler)
throws TException {
...
blogPosts.put(id, blogPost);
final BlogPost stored = blogPost;
resultHandler.onComplete(stored);
}

2. Create a client​

Let's create a client to send a request to the service. You can refer to the full version of the file here of the file.

  1. Create a class for our client. We'll name the class BlogClient.
BlogClient.java
package example.armeria.server.blog.thrift;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BlogClient {
private static final Logger logger = LoggerFactory.getLogger(BlogClient.class);
}
  1. In the BlogClient class, add a constructor and create a Thrift client instance using Armeria's ThriftClients.
BlogClient.java
import java.net.URI;
import com.linecorp.armeria.client.thrift.ThriftClients;
import example.armeria.blog.thrift.BlogService;

public class BlogClient {
...
private final BlogService.Iface blogService;

BlogClient(URI uri, String path) {
blogService =
ThriftClients.builder(uri)
.path(path)
.build(BlogService.Iface.class);
}
}

3. Implement client-side​

In the BlogClient class, add a method to send a request to create a blog post.

BlogClient.java
import org.apache.thrift.TException;
import example.armeria.blog.thrift.BlogPost;
import example.armeria.blog.thrift.CreateBlogPostRequest;
...
BlogPost createBlogPost(String title, String content) throws TException {
final CreateBlogPostRequest request =
new CreateBlogPostRequest().setTitle(title)
.setContent(content);
return blogService.createBlogPost(request);
}

4. Create a test file​

Let's start writing test code. We'll use test code to verify what we implement along the way.

Create a file, BlogServiceTest.java, under {project_root}/src/test/java/example/armeria/server/blog/thrift as follows. You can see the full version of the file here.

BlogServiceTest.java
package example.armeria.server.blog.thrift;

class BlogServiceTest {}

5. Register a ServerExtension​

Armeria's ServerExtension automatically handles set-up and tear-down of a server for testing. This is convenient as it eliminates the need to execute the main method to set up a server before running our tests.

In the BlogServiceTest class, register a ServerExtension as follows. Note that the service instance is added to the configuration.

BlogServiceTest.java
import org.junit.jupiter.api.extension.RegisterExtension;
import com.linecorp.armeria.server.ServerBuilder;
import com.linecorp.armeria.server.thrift.THttpService;
import com.linecorp.armeria.testing.junit5.server.ServerExtension;
...
@RegisterExtension
static final ServerExtension server = new ServerExtension() {
@Override
protected void configure(ServerBuilder sb) throws Exception {
sb.service("/thrift",
THttpService.builder()
// Add the service to the configuration
.addService(new BlogServiceImpl())
.build());
}
};

6. Test creating a blog post​

Let's test if we can create a blog post.

  1. In the BlogServiceTest class, add a test method as follows.
BlogServiceTest.java
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.thrift.TException;
import org.junit.jupiter.api.Test;
import example.armeria.blog.thrift.BlogPost;
...
@Test
void createBlogPost() throws TException {
final BlogClient client = new BlogClient(server.httpUri(), "/thrift");
final BlogPost response = client.createBlogPost("My first blog", "Hello Armeria!");
assertThat(response.getId()).isGreaterThanOrEqualTo(0);
assertThat(response.getTitle()).isEqualTo("My first blog");
assertThat(response.getContent()).isEqualTo("Hello Armeria!");
}
  1. Run the test case on your IDE or using Gradle.
./gradlew test

The service worked as expected if you see the test case passed.

What's next​

In this step, we've implemented a method for creating a blog post. We've also written test code and registered ServerExtension to our test.

Next, at Step 4. Implement READ, we'll implement a READ operation to read a single post and also multiple posts.

Like Armeria?
Star us ⭐️

×