LoginSignup

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

Let's Create a Rest API Service

Last updated at Posted at 2023-10-24

When we talk about Rest API, we usually talk about how to connect and use it. Let's create a service this time.

Rest Event

EFW rest events are stored in the tomcat/WEB-INF/efw/event folder just like web events. The difference is that they are written differently.
https://github.com/efwGrp/efw4.X/blob/master/help/api_restevent.md

Image of Test

Send from jsp to server. Forward from js event to RestAPI event, perform RestAPI DB processing and return the result. A light security check will be performed to check whether the token is correct.
image.png

JSP

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="efw" uri="efw" %>
<!DOCTYPE HTML>
<HTML>
<HEAD>
	<title>Rest API Server and Client Test</title>
	<efw:Client lang="jp"/>
</HEAD>
<BODY>
	<button onclick="Efw('helloRestAPI_submit',{mode:'0'})">初期化(テーブル作成)</button><br><br>
	ID:<input type="text" id="customerId">
	Name:<input type="text" id="customerName"><br>
	token:<input type="text" id="token" value="1234567890">※httpヘッダからセキュリティ情報送信のテスト<br>
	<button onclick="Efw('helloRestAPI_submit',{mode:'1'})">顧客追加</button>
	<button onclick="Efw('helloRestAPI_submit',{mode:'2'})">顧客変更</button>
	<button onclick="Efw('helloRestAPI_submit',{mode:'3'})">顧客削除</button>
	<button onclick="Efw('helloRestAPI_submit',{mode:'4'})">顧客取得</button><br><br>
	<textarea style="width:800px;height:300px;">
	</textarea><br><br>
	<button onclick="Efw('helloRestAPI_submit',{mode:'9'})">終了(テーブル削除)</button><br><br>
</BODY>
</HTML>

Js Event

var helloRestAPI_submit={};
helloRestAPI_submit.paramsFormat={
	mode:null,
	"#customerId":null,
	"#customerName":null,
	"#token":null,
};
helloRestAPI_submit.fire=function(params){
	if (params.mode=="0"){
		db.change("helloRestAPI","createTbl",{});
		return new Result().alert("テーブルを作成しました。");
	}else if (params.mode=="9"){
		db.change("helloRestAPI","dropTbl",{});
		return new Result().alert("テーブルを削除しました。");
	}
	var url="http://localhost:8080/helloworld/efwRestAPI/customer";
	try{
		var ret=null;
		if (params.mode=="1"){//新規追加の場合
			ret=rest.post(url,
				{id:params["#customerId"],nm:params["#customerName"]},
				{token:params["#token"]});
		}else if (params.mode=="2"){//更新の場合
			ret=rest.put(url+"/"+params["#customerId"],
				{nm:params["#customerName"]},
				{token:params["#token"]});
		}else if (params.mode=="3"){//削除の場合
			ret=rest.delete(url+"/"+params["#customerId"],{token:params["#token"]});
		}else if (params.mode=="4"){//取得の場合
			ret=rest.get(url+"/"+params["#customerId"],{token:params["#token"]});
		}
		return new Result()
		.runat("body")
		.withdata({
			"textarea":rest.getStatus()+"\n"+JSON.stringify(ret),
		});
	}catch(e){//失敗の場合
		return new Result()
		.runat("body")
		.withdata({
			"textarea":rest.getStatus()+"\n"+e.getMessage(),
		});
	}
}

RestAPI Event

var customer={};
customer.POST=function(keys,params){//新規作成
	var token=Packages.efw.framework.getRequest().getHeader("token");
	if("1234567890"!=token){throw new Error("セキュリティエラー");}
	db.change("helloRestAPI","insertRow",{"id":params.id,"name":params.nm});
	return {url:"efwRestAPI/customer/"+params.id}
};
customer.PUT=function(keys,params){//更新
	var token=Packages.efw.framework.getRequest().getHeader("token");
	if("1234567890"!=token){throw new Error("セキュリティエラー");}
	var rt=db.change("helloRestAPI","updateRow",{"id":keys[0],"name":params.nm});
	if (rt==0) throw new Error("更新対象のデータは存在しません。");
	return null;
};
customer.DELETE=function(keys){//削除
	var token=Packages.efw.framework.getRequest().getHeader("token");
	if("1234567890"!=token){throw new Error("セキュリティエラー");}
	var rt=db.change("helloRestAPI","deleteRow",{"id":keys[0]});
	if (rt==0) throw new Error("削除対象のデータは存在しません。");
	return null;
};
customer.GET=function(keys){//取得
	var token=Packages.efw.framework.getRequest().getHeader("token");
	if("1234567890"!=token){throw new Error("セキュリティエラー");}
	return db.select("helloRestAPI","selectRow",{"id":keys[0]}).getSingle();
};

Sql

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqls>
<sqls>
<sql id="createTbl">
	CREATE TABLE tbl_customer(
		id character varying(10) NOT NULL,
		name character varying(20),
		CONSTRAINT tbl_customer_pkey PRIMARY KEY (id)
	)
</sql>
<sql id="dropTbl">
	DROP TABLE tbl_customer;
</sql>
<sql id="selectRow">
	SELECT
		id,
		name
	FROM tbl_customer
	WHERE
		id=:id;
</sql>
<sql id="insertRow">
	INSERT INTO tbl_customer(
		id,
		name
	)VALUES (
		:id,
		:name
	);
</sql>
<sql id="updateRow">
	UPDATE tbl_customer
	SET
		name=:name
	WHERE id=:id;
</sql>
<sql id="deleteRow">
	DELETE FROM tbl_customer
	WHERE id=:id;
</sql>
</sqls>

Explanation

POST:insert, url http://localhost:8080/helloworld/efwRestAPI/customer
The return value is the URL of the inserted data, the http status is 200
image.png
PUT:update, url http://localhost:8080/helloworld/efwRestAPI/customer/[customerID]
No return value, http status is 204
image.png

GET:acquisition, http://localhost:8080/helloworld/efwRestAPI/customer/[customerID]
The return value is the retrieved data, http status is 200
image.png

DELETE:delete, http://localhost:8080/helloworld/efwRestAPI/customer/[customerID]
No return value, http status is 204
image.png

When an error occurs,
For example, in the case of duplicate insert keys, no update/delete data, etc.
Return value is error information, http status is 500
image.png
image.png

Test tool connection

image.png

Test from browser

When testing from a browser, the purpose is to see if the implementation is compatible with cors.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="efw" uri="efw" %>
<!DOCTYPE HTML>
<HTML>
<HEAD>
	<title>Rest API Server and Client Test</title>
	<efw:Client lang="jp"/>
</HEAD>
<BODY>
	ID:<input type="text" id="customerId">
	Name:<input type="text" id="customerName"><br>
	token:<input type="text" id="token" value="1234567890">※httpヘッダからセキュリティ情報送信のテスト<br>

<script>
	function browserTest(samedomain){
		var domain=samedomain?"localhost":"127.0.0.1";
		var url="http://"+domain+":8080/helloworld/efwRestAPI/customer/"+$("#customerId").val();
		$.ajax({
			url:url,
			xhrFields: { withCredentials: true },
			headers:{ token:$("#token").val()},
			type: "GET",
			cache: false,
			async: true,
			dataType: "json",// send or get data by json type
			contentType: "application/json;charset=UTF-8",
			success:function(result){
				window.alert(JSON.stringify(result));
			},
			error:function(errorResponse){
				window.alert(JSON.stringify(errorResponse));
			}
		})
	}
</script>
<button onclick="browserTest(true)">ブラウザーテスト</button>
<button onclick="browserTest(false)">別ドメインテスト</button>
</BODY>
</HTML>

The two buttons send from localhost and 127.0.0.1 respectively. And when you compare it with the referer, one will always be judged as cors.
The first time is to send options.
image.png
The second time is a get transmission.
image.png

This is a link for explanations related to cors.
https://qiita.com/tomoyukilabs/items/81698edd5812ff6acb34

Environmental Preparation

Since DB is also used, please refer to the following article.
https://qiita.com/changkejun/items/b273b3ae64c76e5b016a

This sample can be downloaded from the link below.

0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up