Skip to content

Do Not Repeat Yourself API. Strictly typed API using Jooq/Jackson/Immutables objects as definition of data.

License

Notifications You must be signed in to change notification settings

NavigoSolutions/dry-api

Repository files navigation

dry-api (Don't Repeat Yourself API)

Warning: work in progress!

Main purpose

Library for creating Java APIs.

Simplify writing APIs for CRUD applications. Assure consistency. Handle security. Write data structures once and reuse many times.

It originates in system Navigo3 for managing project-based companies on all levels from work reports to company KPIs.

Architecture

  • API is completely described in code, no config files

  • Inputs and outputs are strictly typed on both sides (client&server)

  • Definition and implementation of API methods are separed so you can provide only definition to client but still stay strictly typed

  • Supports directly data structures generated by Jooq/Immutables/Jackson libraries

  • API is validated by compiler - any change in data structures will cause compilation error

Capabilities

  • Provides data as JSON or XML

  • Data can be transported by arbitrary protocol, for example HTTP

  • By default enforces data structures validation, but supports also custom business rules validation

  • Supports declarative authorization on call level

  • Allows declarative authorization on field level of inputs/outputs

  • Generates API catalogue from metadata

Sample API method

Sample of method, that adds two integers and return result.

Data structures:

@Value.Immutable
@JsonSerialize(as = ImmutableIntegerOperands.class)
@JsonDeserialize(as = ImmutableIntegerOperands.class)
public interface IntegerOperands {
	int getA();
	int getB();
}

@Value.Immutable
@JsonSerialize(as = ImmutableIntegerResult.class)
@JsonDeserialize(as = ImmutableIntegerResult.class)
public interface IntegerResult {
	int getRes();
}

Definition:

public class AddIntegersEndpoint extends MethodDefinition<IntegerOperands, IntegerResult> {
	
	@Override
	public TypeReference<IntegerOperands> getInputType() {
		return new TypeReference<IntegerOperands>() {};
	}

	@Override
	public TypeReference<IntegerResult> getOutputType() {
		return new TypeReference<IntegerResult>() {};
	}

	@Override
	public String getName() {
		return "test/integer/add";
	}
}

Implementation:

public class AddIntegersImpl extends MethodImplementation<IntegerOperands, IntegerResult> {

	@Override
	public IntegerResult execute(IntegerOperands input) {
		return ImmutableIntegerResult
			.builder()
			.res(input.getA()+input.getB())
			.build();
	}
	
}

Use (TBD):

public class Sandbox {

	@Test
	public void test() {
		ApiRegistry registry = new ApiRegistry();
		registry.register(new AddIntegersEndpoint(), AddIntegersImpl.class);
		
		JsonGate gate = new JsonGate(registry);
		
		//Just imagine input and output JSON is transported through HTTP or something similar

		String result = gate.execute(new AddIntegersEndpoint().getName(), "{\"a\":40, \"b\":2}");

		assertEquals(result, "{\"result\":\"success\",\"output\":{\"res\":42}}");
	}
	
}

About

Do Not Repeat Yourself API. Strictly typed API using Jooq/Jackson/Immutables objects as definition of data.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published