Kotlin Language Features Related to Null Handling

Any software engineer with a Java background would find the null handling features in the Kotlin language interesting. Let's summarize this topic with some examples. Nullable types: In Kotlin, types are non-nullable by default. If you want a variable to be able to hold a null value, you need to explicitly declare its type as nullable using the Type? syntax. For example, String? denotes a nullable string, while String represents a non-nullable string. Safe calls (?.): Kotlin introduces the safe call operator (?.) for handling nullable types. It allows you to safely invoke a method or access a property on a nullable object. If the object is null, the expression returns null instead of throwing a NullPointerException. Example: data class Person(val name: String, val age: Int, val address: String?) fun main() {     // Create a person with a nullable address     val person1 = Person("John Doe", 25, "123 Main Street")     val person2 = Person("Jane Doe", 30,...

Building and Testing Rest services with Spring

I realized that I need to learn more on Spring Boot/Spring REST and integration testing stuff. Here it goes!

Let us remember: Spring Boot project aims at making it easier to build Spring applications by eliminating the need for extensive configuration. With default settings, you can feel magic tricks like implementing your interface behind the scenes etc.

About REST: Have you ever worked with SOAP? How did it feel? For me, it always felt like something wrong was going on. Something simpler is needed. Then I was able to see in practice that REST services offer cleaner solutions and with the great capabilities of Java platform and Spring, you have a far better structure.

HTTP is the Platform

You describe the relationships using URIs. For example, you access the Bookmark's of a User with:

/alice/bookmarks

Clients and services agree upon a mutually understood data representation. So we send HTTP GET/POST/DELETE requests. There is usually a status code about the result of the operation.

Example: Status code 404: Your request is incorrect.

With Spring, you implement a rest controller:

@RestController
@RequestMapping("/{userId}/bookmarks")
class BookmarkRestController {

private final BookmarkRepository bookmarkRepository;
private final AccountRepository accountRepository;

@Autowired
BookmarkRestController(BookmarkRepository bookmarkRepository,
  AccountRepository accountRepository) {
this.bookmarkRepository = bookmarkRepository;
this.accountRepository = accountRepository;
}

@RequestMapping(method = RequestMethod.GET)
Collection readBookmarks(@PathVariable String userId) {
this.validateUser(userId);
return this.bookmarkRepository.findByAccountUsername(userId);
}
...
}

@RestController exposes the annotated bean’s methods as HTTP endpoints

Controller methods return simple POJOs - Collection, and Bookmark, etc. When an HTTP request comes in that specifies an Accept header, Spring MVC loops through the configured HttpMessageConverter until it finds one that can convert from the POJO domain model types into the content-type specified in the Accept header, if so configured. Spring Boot automatically wires up an HttpMessageConverter that can convert generic Object s to JSON, absent any more specific converter. HttpMessageConverter s work in both directions: incoming requests bodies are converted to Java objects, and Java objects are converted into HTTP response bodies.


Testing a REST Service


@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@WebAppConfiguration
public class BookmarkRestControllerTest {

    private MockMvc mockMvc;

    private Account account;

    private List bookmarkList = new ArrayList<>();

    @Autowired
    private BookmarkRepository bookmarkRepository;

    @Autowired
    private WebApplicationContext webApplicationContext;

    @Autowired
    private AccountRepository accountRepository;

    @Test
    public void userNotFound() throws Exception {
        mockMvc.perform(post("/george/bookmarks/")
                .content(this.json(new Bookmark()))
                .contentType(contentType))
                .andExpect(status().isNotFound());
    }

    @Test
    public void readSingleBookmark() throws Exception {
        mockMvc.perform(get("/" + userName + "/bookmarks/"
                + this.bookmarkList.get(0).getId()))
                .andExpect(status().isOk())
                .andExpect(content().contentType(contentType))
                .andExpect(jsonPath("$.id", is(this.bookmarkList.get(0).getId().intValue())))
                .andExpect(jsonPath("$.uri", is("http://bookmark.com/1/" + userName)))
                .andExpect(jsonPath("$.description", is("A description")));
    }
...
}

Using Spring REST with Vaadin


@Theme("valo")
@SpringUIpublic class MyVaadinSpringUI extends UI {

    @Autowired    MyRestController myRestController;

    @Override    protected void init(VaadinRequest vaadinRequest) {

        VerticalLayout verticalLayout = new VerticalLayout();

        Button button = new Button("Invoke controller");

        button.addClickListener(new Button.ClickListener() {
            @Override            public void buttonClick(Button.ClickEvent clickEvent) {

                int result = myRestController.readBookmarks();

                Notification.show("");

                Notification notification = new Notification(String.valueOf(result));
                notification.setDelayMsec(40000);
                notification.show(Page.getCurrent());
            }
        });

        verticalLayout.addComponent(button);

        setContent(verticalLayout);
    }

    @WebListener    public static class SpringContextLoaderListener extends ContextLoaderListener {
    }

    @Configuration    @EnableVaadin    @EnableVaadinNavigation    public static class SpringConfiguration {
    }

    @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
    @VaadinServletConfiguration(ui = MyVaadinSpringUI.class, productionMode = false)
    public static class MyUIServlet extends SpringVaadinServlet {
    }

}

@RestController@RequestMapping("/hello")
class MyRestController {

   @RequestMapping(method = RequestMethod.GET)
   int readMyNumber() {
      return 100;
   }

Comments

Popular posts from this blog

Trie Data Structure and Finding Patterns in a Collection of Words

Virtual Memory

NOTES ON COMPUTER ARCHITECTURE: Some important concepts in computer architecture