type HelloRequest {
name:string
}
interface HelloInterface {
requestResponse:
hello( HelloRequest )( string )
}
service HelloService {
execution: concurrent
inputPort HelloService {
location: "socket://localhost:9000"
protocol: http { format = "json" }
interfaces: HelloInterface
}
main {
hello( request )( response ) {
response = "Hello " + request.name
}
}
}
Jolie crystallises the programming concepts of service-oriented computing as linguistic constructs. The basic building blocks of software are not objects or functions, but rather services that can be relocated and replicated as needed. A composition of services is a service.
Jolie is a contract-first programming language, which puts API design at the forefront. It supports both synchronous and asynchronous communication. Data models are defined by types that support refinement (in red on the right), and DTO (Data Transfer Objects) transformations are transparently managed by the interpreter.
type GetProfileRequestType {
id:int
}
type GetProfileResponseType {
name:string
surname:string
email:string( regex(".*@.*\\\\..*") )
accounts[0,*] {
nickname:string
service_url:string
enabled:bool
}
ranking:int( ranges( [1,5] ) )
}
type SendMessageRequestType {
id:int
message:string( length( [0,250] ) )
}
interface ProfileInterface {
requestResponse: // Synchronous RPC
getProfile( GetProfileRequestType )( GetProfileResponseType )
oneWay: // Asynchronous
sendMessage( SendMessageRequestType )
}
Jolie code is always contained in services, which you can always move from being local to remote and vice versa, without altering the logic of your programs. A monolithical application can scale to being distributed by design: if you decide to distribute a part of it, just take it and execute it in another machine.




Jolie is protocol agnostic: your services can exchange data by using different protocols. Bridging two networks using different protocols is a matter of a few lines of code. If you need a protocol that Jolie does not support yet, there is an API for developing new ones in Java.

type HelloRequest {
name:string
}
interface HelloInterface {
requestResponse:
hello( HelloRequest )( string )
}
service HelloService {
execution { concurrent }
inputPort HelloServiceHTTP {
location: "socket://localost:9000"
protocol: http { format = "json" }
interfaces: HelloInterface
}
inputPort HelloServiceSOAP {
location: "socket://localost:9001"
protocol: soap {
wsdl = "myWsdl.wsdl"
wsdl.port = "MyServiceSOAPPort"
}
interfaces: HelloInterface
}
inputPort HelloServiceSODEP {
location: "socket://localost:9002"
protocol: sodep
interfaces: HelloInterface
}
main {
// This can now be reached through HTTP/JSON, SOAP, or SODEP (binary)
hello( request )( response ) {
response = "Hello " + request.name
}
}
}
Jolie comes with native primitives for structuring workflows, for example in sequences (one after the other) or parallels (go at the same time). This makes the code follow naturally from the requirements, avoiding error-prone bookkeeping variables for checking what happened so far in a computation. For example, the following code says that the operations publish and edit become available at the same time (|), but only after (;) operation login is invoked: