Create a new e-Service

This tutorial explains how to implement a new e-Service in FREME. A FREME e-Service is an enrichment service for Natural Language Processing exposed via a REST API and that follows the NIF API specifications.

Explanation of the e-Service

This e-Service enriches each text with a capitalized version of it. Like all FREME e-Services it takes NIF or plaintext as input. Example for NIF input is

@prefix nif:<http://persistence.uni-leipzig.org/nlp2rdf/ontologies/nif-core#> .
@prefix itsrdf: <http://www.w3.org/2005/11/its/rdf#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<http://example.org/document/1#char=0,21>
  a nif:String , nif:Context, nif:RFC5147String ;
  nif:isString "Welcome to Berlin"^^xsd:string;
  nif:beginIndex "0"^^xsd:nonNegativeInteger;
  nif:endIndex "21"^^xsd:nonNegativeInteger;
  nif:sourceUrl <http://differentday.blogspot.com/2007_01_01_archive.html>.

An example CURL request to the e-Service is

curl -X POST "http://localhost:8080/example-eservice/capitalize?input=hello+world&informat=text"

The output of above example is

@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
@prefix nif:   <http://persistence.uni-leipzig.org/nlp2rdf/ontologies/nif-core#> .

<http://freme-project.eu/#char=0,11>
        a               nif:RFC5147String , nif:Context , nif:String ;
        <http://freme-project.eu/capitalize>
                "HELLO WORLD"^^xsd:string ;
        nif:beginIndex  "0"^^xsd:nonNegativeInteger ;
        nif:endIndex    "11"^^xsd:nonNegativeInteger ;
        nif:isString    "hello world" .

Example code

You can use this boilerplate code to create an e-Service in the source code of the broker. The full code example (including imports) can be downloaded here. Similar e-Services are implement in the broker in the package eu.freme.broker.eservices.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
@RestController
public class ExampleEService extends BaseRestController {

	@Autowired
	RDFConversionService rdfConversionService;

	Logger logger = Logger.getLogger(ExampleEService.class);

	@RequestMapping(value = "/example-eservice/capitalize", method = RequestMethod.POST)
	public ResponseEntity<String> tildeTranslate(
			@RequestHeader(value = "Accept", required = false) String acceptHeader,
			@RequestHeader(value = "Content-Type", required = false) String contentTypeHeader,
			@RequestBody(required = false) String postBody,
			@RequestParam Map<String, String> parameterMap) {

		NIFParameterSet parameters = this.normalizeNif(postBody, acceptHeader,
				contentTypeHeader, parameterMap, false);

		// create rdf model
		String plaintext = null;
		Model inputModel = ModelFactory.createDefaultModel();

		if (!parameters.getInformat().equals(
				RDFConstants.RDFSerialization.PLAINTEXT)) {
			// input is nif
			try {
				inputModel = this.unserializeNif(parameters.getInput(),
						parameters.getInformat());
			} catch (Exception e) {
				logger.error("failed", e);
				throw new BadRequestException("Error parsing NIF input");
			}
		} else {
			// input is plaintext
			plaintext = parameters.getInput();
			rdfConversionService.plaintextToRDF(inputModel, plaintext, null,
					parameters.getPrefix());
		}

		try {
			Property property = inputModel.getProperty("http://persistence.uni-leipzig.org/nlp2rdf/ontologies/nif-core#isString");	
			Statement stmt = inputModel.listStatements((Resource)null, property, (String)null).next();
			plaintext = stmt.getLiteral().getString();
			String enrichment = plaintext.toUpperCase();
			Property enrichmentProperty = inputModel.createProperty("http://freme-project.eu/capitalize");		
			stmt.getSubject().addLiteral(enrichmentProperty, enrichment);
		} catch (Exception e) {
			logger.error("exception was thrown", e);
			throw new InternalServerErrorException();
		}

		return createSuccessResponse(inputModel, parameters.getOutformat());
	}
}

Useful links:

Embedding the e-Service in FREME

FREME differentiates between two kinds of e-Services. e-Services hosted on FREME and external services.

An external service is a service that is hosted on another server and that is accessible via a web interface. So FREME proxies the requests it receives to this server. In this case FREME adds NIF compatibility and more input / output formats to the external service. This is the easiest way of integrating an e-Service into FREME. In this case you can directly implement the API call in line 44 of the example code.

An e-Service hosted on FREME is more complicated. In this case FREME does not simply redirect the call to an external service but the code that produces the enrichment resides on FREME also. We suggest to implement this enrichment service as a separate project and as a Java library. It should be implemented as a spring bean for easy integration in FREME. Then the e-Service calls this Java library.