Ideate, Develop and Manage API-first micro services with SAP Cloud Platform, API Management
APIs have become the most common way for various services to communicate with each other.Micro services architecture on the other hand has gained popularity over the past few years because of its ability to loosely couple services and providing business solution as per the needs. Combining the two ideologies and practices this blog gives an approach using the OpenAPI standards so that the APIs can be easily managed and maintained in the following phases.
Ideation phase -> Develop the API ->Proxify the API ->Consume the API
The code can be fount at Github
Ideate and Develop APIs
We are going to create APIs using SpringBoot framework in Java. SpringBoot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”. The idea is to create micro-services and create APIs adhering to the OpenAPI spec using Swagger. For storing the data we are going to use MongoDB as the no-sql database .
We are going to create a Product catalog having the basic CRUD operations.
For creating the APIs- Define the APIs along with the Swagger information
package com.controllers;
@RestController
public class ProductController {
private ProductService productService;
public static final String PLAIN_RESPONSE_TYPE = "text/plain";
public static final String JSON_RESPONSE_TYPE = "application/json";
public static final String COLLECTION_NAME = "productCollection";
boolean USE_CF = true;
@Autowired
public void setProductService() {
this.productService = new ProductServiceImpl(COLLECTION_NAME, USE_CF, MONGO_LOCAL_HOST_URL);
}
@ApiOperation(value = "Creates a product")
@RequestMapping(value = "/product/create", method = RequestMethod.POST, produces = PLAIN_RESPONSE_TYPE)
public ResponseEntity<?> addProduct(@RequestBody Product product) {
Product createdProduct = productService.createProduct(product);
return new ResponseEntity<>("New Product added successfully", HttpStatus.OK);
}
@ApiOperation(value = "Updates a product")
@RequestMapping(value = "/product/update/{productId}", method = RequestMethod.PUT, produces = PLAIN_RESPONSE_TYPE)
public ResponseEntity<?> updateProduct(@PathVariable String productId, @RequestBody Product updatedProduct) {
productService.updateProduct(updatedProduct);
return new ResponseEntity<>("Product updated successfully", HttpStatus.OK);
}
@ApiOperation(value = "List all available products", response = Iterable.class)
@ApiResponses(value = { @ApiResponse(code = 200, message = "Successfull in finding the list"),
@ApiResponse(code = 404, message = "The resource you were trying to reach is not found") })
@RequestMapping(value = "/product/list", method = RequestMethod.GET, produces = "application/json")
public Iterable<Product> list() {
Iterable<Product> productList = productService.findAllProducts();
return productList;
}
@ApiOperation(value = "Find product with an Id", response = Product.class)
@RequestMapping(value = "/product/find/{productId}", method = RequestMethod.GET, produces = JSON_RESPONSE_TYPE)
public Product findProduct(@PathVariable String productId) {
Product product = productService.getProductById(productId);
return product;
}
@ApiOperation(value = "Delete a product")
@RequestMapping(value = "/product/delete/{productId}", method = RequestMethod.DELETE, produces = PLAIN_RESPONSE_TYPE)
public ResponseEntity<?> delete(@PathVariable String productId) {
productService.deleteProduct(productId);
return new ResponseEntity<>("Product deleted successfully", HttpStatus.OK);
}
}
The Swagger Configuration..
package com.controllers;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket postsApi() {
return new Docket(DocumentationType.SWAGGER_2).groupName("public-api")
.apiInfo(apiInfo()).select().paths(postPaths()).build();
}
private Predicate<String> postPaths() {
return PathSelectors.regex("/product.*");
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("Product Catalog listing")
.description("Product Catalog reference for developers")
.version("1.0").build();
}
}
Once the application is deployed the app creates the Swagger-ui which can be found at
/swagger-ui.html.
The swagger html page helps to play with the APIs which are just created.
The Swagger json is also generated and can be found at the following location
/v2/api-docs?group=public-api
{"swagger":"2.0","info":{"description":"Product Catalog reference for developers","version":"1.0","title":"Product Catalog listing"},"host":"springbootswagger-nonbureaucratic-baseline.cfapps.eu10.hana.ondemand.com","basePath":"/","tags":[{"name":"product-controller","description":"Product Controller"}],"paths":{"/product/create":{"post":{"tags":["product-controller"],"summary":"Creates a product","operationId":"addProductUsingPOST","consumes":["application/json"],"produces":["text/plain"],"parameters":[{"in":"body","name":"product","description":"product","required":true,"schema":{"$ref":"#/definitions/Product"}}],"responses":{"200":{"description":"OK","schema":{"type":"object"}},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/product/delete/{productId}":{"delete":{"tags":["product-controller"],"summary":"Delete a product","operationId":"deleteUsingDELETE","consumes":["application/json"],"produces":["text/plain"],"parameters":[{"name":"productId","in":"path","description":"productId","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"type":"object"}},"401":{"description":"Unauthorized"},"204":{"description":"No Content"},"403":{"description":"Forbidden"}}}},"/product/find/{productId}":{"get":{"tags":["product-controller"],"summary":"Find product with an Id","operationId":"findProductUsingGET","consumes":["application/json"],"produces":["application/json"],"parameters":[{"name":"productId","in":"path","description":"productId","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/Product"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/product/list":{"get":{"tags":["product-controller"],"summary":"List all available products","operationId":"listUsingGET","consumes":["application/json"],"produces":["application/json"],"responses":{"200":{"description":"Successfull in finding the list","schema":{"$ref":"#/definitions/Iterable"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"The resource you were trying to reach is not found"}}}},"/product/update/{productId}":{"put":{"tags":["product-controller"],"summary":"Updates a product","operationId":"updateProductUsingPUT","consumes":["application/json"],"produces":["text/plain"],"parameters":[{"name":"productId","in":"path","description":"productId","required":true,"type":"string"},{"in":"body","name":"updatedProduct","description":"updatedProduct","required":true,"schema":{"$ref":"#/definitions/Product"}}],"responses":{"200":{"description":"OK","schema":{"type":"object"}},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}}},"definitions":{"Iterable«Product»":{"type":"object"},"Iterable":{"type":"object"},"Product":{"type":"object","properties":{"description":{"type":"string"},"imageUrl":{"type":"string"},"price":{"type":"number","format":"double"},"productId":{"type":"string"}}}}}
Proxify the API
This swagger json helps us to create proxy APIs with the help of API Management easily and effectively. Every-time there is change in the Java Code of the API, this swagger can be generated and the proxy APIs can be modified without a hassle.
Use this generated swagger json to create and proxify APIs with the SAP API Management tool.
In the Api Managmenet Portal go to ->develop->Import Api-> Import the Swagger Json.
Once the Swagger json is uploaded, the following is created automatically
Deploy the API using the ‘Save and Deploy’ button.
Consume the API
The API is deployed and the proxy URL is ready to serve. To check use
https://proxified_URL/product/list
It should give the list of products available .
Now when the developer is modifying the APIs as per business needs, modifying the proxy becomes easy.Just regenerate the swagger and upload again. The new set of APIs/updated APIs would be ready to proxify.
For monetizing and metering the API have a look at my earlier post