title | order | layout |
---|---|---|
Accessing Java Backend in TypeScript |
60 |
page |
An API endpoint is a backend method that is exposed for calling from client-side TypeScript code.
Vaadin endpoint is a class that defines one or more API methods.
Vaadin bridges Java backend endpoints and a TypeScript frontend. It generates TypeScript clients to call the Java backend in a type-checkable way.
Warning
|
Vaadin endpoint depends on Spring Boot auto-configuration. It does not work if the auto-configuration is disabled, for example, when you use @EnableWebMvc . A simple workaround is to remove the @EnableWebMvc annotation, as stated in this Spring Boot doc.
If you have an idea how to make it more useful for you, please share it on GitHub.
|
Annotate any existing class with the @Endpoint
annotation or create such
class from scratch:
import com.vaadin.flow.server.connect.Endpoint;
import com.vaadin.flow.server.connect.auth.AnonymousAllowed;
/**
* A Vaadin endpoint that counts numbers.
*/
@Endpoint
@AnonymousAllowed
public class CounterEndpoint {
/**
* A method that adds one to the argument.
*/
public int addOne(int number) {
return number + 1;
}
}
After that, when the application starts, Vaadin analyzes such classes in order
to be able to process the requests made to such endpoints, and to appropriately
verify user access. For each request that is trying to access the method in the
corresponding Vaadin endpoint, a permission check is carried on. @AnonymousAllowed
means that it permits anyone to call the method via the request without the authorization
. Please refer to the Security page
for configuring endpoint access.
In JavaScript and TypeScript, modules are files that follow the module syntax. This syntax has the following properties:
-
The top-level declarations (variables, functions, classes, etc.) are scoped inside the module, meaning that they are not available outside by default.
-
Modules support top-level
export
statements, which make declarations available for other modules. -
Modules supports top-level
import
statements, which load and execute other modules, and can bring exported declarations.
The following example demonstrates the City.ts
module:
// declare and export an interface
export default interface City {
country: string;
}
// import and use a declaration from another module
import {City} from './City';
const cityObject: City = {
name: "Turku",
country: "Finland"
};
// Note: cityObject is not exported, thus it is only available in this file
In Vaadin applications, the index.ts
(or, optionally, index.js
) file is also a module.
There is a generated TypeScript module for every Vaadin endpoint on the backend. Each module exports all the methods.
You can either import the whole generated module as an endpoint, or import the
methods from the module separately. For instance, the
CounterEndpoint.ts
could be used as in the following snippets:
// Other imports
import * as counterEndpoint from './generated/CounterEndpoint';
// Other code
counterEndpoint.addOne(1).then(result => console.log(result));
// Other imports
import {addOne} from './generated/CounterEndpoint';
// Other code
addOne(1).then(result => console.log(result));
The generation is done automatically when the application compiles, and when the application is running in development mode.
By default, the generated files are located under {project.basedir}/frontend/generated
.
You can change the folder by providing the path for the generator in the
generatedFrontendDirectory
property for Vaadin Maven plugin.
Vaadin takes care of type conversion between Java and TypeScript types, for more info about supported types visit the Type Conversion appendix.
For example, the generated TypeScript module for the Java endpoint defined in CounterEndpoint.java would look like:
/**
* A Vaadin endpoint that counts numbers.
*
* This module has been generated from CounterEndpoint.java
* @module CounterEndpoint
*/
import client from './connect-client.default';
/**
* A method that adds one to the argument.
*
* @param number
*/
export async function addOne(number: number) {
return await client.call('CounterEndpoint', 'addOne', {number});
}