From a0ff867b664537a834a94d31b41270b69d16afea Mon Sep 17 00:00:00 2001 From: badbuta Date: Thu, 21 Dec 2023 01:04:32 +0800 Subject: [PATCH] Add swagger, more endpoints --- .../ApiController.java | 57 +++------ .../MainApplication.java | 2 + .../UserController.java | 58 +++++++++ .../{ => entities}/User.java | 4 +- .../mapper/UserMapper.java | 15 +++ .../learnspringbootrestfulsqlite/openapi.yml | 110 ++++++++++++++++++ .../services/UserService.java | 30 +++++ src/main/resources/application.properties | 14 ++- src/main/resources/mapper/mainapp.xml | 9 -- src/main/resources/mapping/UserMapper.xml | 29 +++++ src/main/resources/mybatis/config.xml | 18 --- src/main/resources/mybatis/mybatis-config.xml | 24 ++++ 12 files changed, 299 insertions(+), 71 deletions(-) create mode 100644 src/main/java/com/badbuta/learnspringbootrestfulsqlite/UserController.java rename src/main/java/com/badbuta/learnspringbootrestfulsqlite/{ => entities}/User.java (90%) create mode 100644 src/main/java/com/badbuta/learnspringbootrestfulsqlite/mapper/UserMapper.java create mode 100644 src/main/java/com/badbuta/learnspringbootrestfulsqlite/openapi.yml create mode 100644 src/main/java/com/badbuta/learnspringbootrestfulsqlite/services/UserService.java delete mode 100644 src/main/resources/mapper/mainapp.xml create mode 100644 src/main/resources/mapping/UserMapper.xml delete mode 100644 src/main/resources/mybatis/config.xml create mode 100644 src/main/resources/mybatis/mybatis-config.xml diff --git a/src/main/java/com/badbuta/learnspringbootrestfulsqlite/ApiController.java b/src/main/java/com/badbuta/learnspringbootrestfulsqlite/ApiController.java index da78cce..e606a00 100644 --- a/src/main/java/com/badbuta/learnspringbootrestfulsqlite/ApiController.java +++ b/src/main/java/com/badbuta/learnspringbootrestfulsqlite/ApiController.java @@ -2,34 +2,39 @@ package com.badbuta.learnspringbootrestfulsqlite; import org.springframework.web.bind.annotation.RestController; +import com.badbuta.learnspringbootrestfulsqlite.entities.User; import com.google.gson.Gson; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import java.io.IOException; import java.util.List; -import java.util.Map; import java.io.Reader; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; /** * The RESTful API Controller Class - * The URL for this API Controller is '/api' + * The URL for this API Controller is '/api/v1' + * + * NOTE: By adding @CrossOrigin, Swagger preview can work perfectly. + * */ @RestController -@RequestMapping(value = "/api") +@CrossOrigin +@RequestMapping(value = "/api/v1") public class ApiController { - // TODO Load the config from application.properties rather than var - public static String MY_BATIS_CONFIG = "mybatis/config.xml"; + @Value("${mybatis.config-location}") + private String myBatisConfigLocation; /** * API Endpoint = /api (or /api/) @@ -49,17 +54,13 @@ public class ApiController { // return "GET /test, param: a=" + valA; // } - /** - * Get the user(s) by id (using query-string param) - * - * @param id The ID for - * @return User object in JSON - */ - @GetMapping("users") + @GetMapping("fix") public String getUsers() { Gson gson = new Gson(); - try (Reader in = Resources.getResourceAsReader(MY_BATIS_CONFIG)) { + String myBatisConfigPath = myBatisConfigLocation.split(":")[1]; + + try (Reader in = Resources.getResourceAsReader(myBatisConfigPath)) { // Create SQL Session Factory from mybatis config SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in); @@ -67,39 +68,17 @@ public class ApiController { SqlSession session = factory.openSession(); // Select users - List> result = session.selectList("mainapp.mybatis.selectUsers"); + List result = session + .selectList("com.badbuta.learnspringbootrestfulsqlite.mapper.UserMapper.getUsers"); return gson.toJson(result); } catch (IOException e) { // If exception, return the exception object in JSON // TODO: it is not a good practice and should return formatted error object + System.err.println(e); return gson.toJson(e); } } - - @GetMapping("users/{id}") - public String getUsersById(@RequestParam(name = "id", required = false) String id) { - Gson gson = new Gson(); - - try (Reader in = Resources.getResourceAsReader(MY_BATIS_CONFIG)) { - // Create SQL Session Factory from mybatis config - SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in); - - // Create session - SqlSession session = factory.openSession(); - - // Select users - List> result = session.selectList("mainapp.mybatis.selectUsers"); - - return gson.toJson(result); - - } catch (IOException e) { - // If exception, return the exception object in JSON - // TODO: it is not a good practice and should return formatted error object - return gson.toJson(e); - } - } - } diff --git a/src/main/java/com/badbuta/learnspringbootrestfulsqlite/MainApplication.java b/src/main/java/com/badbuta/learnspringbootrestfulsqlite/MainApplication.java index cde552e..9107b70 100644 --- a/src/main/java/com/badbuta/learnspringbootrestfulsqlite/MainApplication.java +++ b/src/main/java/com/badbuta/learnspringbootrestfulsqlite/MainApplication.java @@ -1,9 +1,11 @@ package com.badbuta.learnspringbootrestfulsqlite; +import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication +@MapperScan("com.badbuta.learnspringbootrestfulsqlite.mapper") public class MainApplication { public static void main(String[] args) { diff --git a/src/main/java/com/badbuta/learnspringbootrestfulsqlite/UserController.java b/src/main/java/com/badbuta/learnspringbootrestfulsqlite/UserController.java new file mode 100644 index 0000000..fe75cd3 --- /dev/null +++ b/src/main/java/com/badbuta/learnspringbootrestfulsqlite/UserController.java @@ -0,0 +1,58 @@ +package com.badbuta.learnspringbootrestfulsqlite; + +import org.springframework.web.bind.annotation.RestController; + +import com.badbuta.learnspringbootrestfulsqlite.entities.User; +import com.badbuta.learnspringbootrestfulsqlite.services.UserService; +import org.springframework.web.bind.annotation.RequestMapping; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +/** + * The RESTful API Controller Class + * The URL for this API Controller is '/api/v1' + * + * NOTE: By adding @CrossOrigin, Swagger preview can work perfectly. + * + */ +@RestController +@CrossOrigin +@RequestMapping(value = "/api/v1") +public class UserController { + @Autowired + private UserService userService; + + /** + * Get the user(s) by id (using query-string param) + * + * @param id The ID for + * @return User object in JSON + */ + @GetMapping(value = "users", produces = "application/json") + public List getUsers() { + List users = userService.getUsers(); + return users; + + } + + @GetMapping(value = "users/{id}", produces = "application/json") + public User getUsersById(@PathVariable("id") String userId) { + User user = userService.getUserById(Integer.parseInt(userId)); + return user; + + } + + @PostMapping("users") + public User insertUser(@RequestBody User user) { + // TODO: Return always 1, need to fix + int id = userService.insertUser(user); + user.setId(id); + return user; + } + +} diff --git a/src/main/java/com/badbuta/learnspringbootrestfulsqlite/User.java b/src/main/java/com/badbuta/learnspringbootrestfulsqlite/entities/User.java similarity index 90% rename from src/main/java/com/badbuta/learnspringbootrestfulsqlite/User.java rename to src/main/java/com/badbuta/learnspringbootrestfulsqlite/entities/User.java index f2a8e15..cdeb965 100644 --- a/src/main/java/com/badbuta/learnspringbootrestfulsqlite/User.java +++ b/src/main/java/com/badbuta/learnspringbootrestfulsqlite/entities/User.java @@ -1,7 +1,7 @@ -package com.badbuta.learnspringbootrestfulsqlite; +package com.badbuta.learnspringbootrestfulsqlite.entities; /** - * Domain class - user + * Domain class - User */ public class User { diff --git a/src/main/java/com/badbuta/learnspringbootrestfulsqlite/mapper/UserMapper.java b/src/main/java/com/badbuta/learnspringbootrestfulsqlite/mapper/UserMapper.java new file mode 100644 index 0000000..ee5fa58 --- /dev/null +++ b/src/main/java/com/badbuta/learnspringbootrestfulsqlite/mapper/UserMapper.java @@ -0,0 +1,15 @@ +package com.badbuta.learnspringbootrestfulsqlite.mapper; + +import java.util.List; +import org.springframework.stereotype.Repository; + +import com.badbuta.learnspringbootrestfulsqlite.entities.User; + +@Repository +public interface UserMapper { + int insertUser(User user); + + User getUserById(int id); + + List getUsers(); +} diff --git a/src/main/java/com/badbuta/learnspringbootrestfulsqlite/openapi.yml b/src/main/java/com/badbuta/learnspringbootrestfulsqlite/openapi.yml new file mode 100644 index 0000000..7d56dcb --- /dev/null +++ b/src/main/java/com/badbuta/learnspringbootrestfulsqlite/openapi.yml @@ -0,0 +1,110 @@ +openapi: "3.0.2" +info: + title: Learn Spring Boot RESTful API (SQLite) + version: "1.0" + description: This is an initial draft of API Spec., not generated. +servers: + - url: http://localhost:8888/api/v1 + +paths: + /users: + get: + summary: Get all users + responses: + "200": + description: OK + content: + application/json: + schema: + type: array + items: + type: object + $ref: "#/components/schemas/User" + + post: + summary: Insert a user + requestBody: + description: User object for insertion + required: true + content: + application/json: + schema: + type: object + properties: + name: + type: string + example: David + password: + type: string + example: 9ff1a0c82d7268b89aeeb112c7f9250b + description: hashed password + # $ref: "#/components/schemas/User" + example: + name: john + password: 9ff1a0c82d7268b89aeeb112c7f9250b + + responses: + "201": + description: "The user account has been created" + content: + application/json: + schema: + type: object + $ref: "#/components/schemas/User" + "default": + description: "Unexpected error" + content: + application/json: + schema: + type: array + items: + type: object + $ref: "#/components/schemas/Error" + /users/{id}: + get: + summary: Get a users + parameters: + - in: path + name: id + schema: + type: number + example: 1 + required: true + description: User Id for query + + responses: + "200": + description: OK + content: + application/json: + schema: + type: array + items: + type: object + $ref: "#/components/schemas/User" + +components: + schemas: + User: + properties: + id: + type: integer + example: 123 + description: zero-based User ID + name: + type: string + example: David + password: + type: string + example: 9ff1a0c82d7268b89aeeb112c7f9250b + description: hashed password + required: + - id + + Error: + properties: + code: + type: string + message: + type: string + diff --git a/src/main/java/com/badbuta/learnspringbootrestfulsqlite/services/UserService.java b/src/main/java/com/badbuta/learnspringbootrestfulsqlite/services/UserService.java new file mode 100644 index 0000000..d88708a --- /dev/null +++ b/src/main/java/com/badbuta/learnspringbootrestfulsqlite/services/UserService.java @@ -0,0 +1,30 @@ +package com.badbuta.learnspringbootrestfulsqlite.services; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.badbuta.learnspringbootrestfulsqlite.entities.User; +import com.badbuta.learnspringbootrestfulsqlite.mapper.UserMapper; + +@Service +public class UserService { + @Autowired + UserMapper userMapper; + + public int insertUser(User user) { + int insteredUserId = userMapper.insertUser(user); + return insteredUserId; + } + + public User getUserById(int id) { + return userMapper.getUserById(id); + } + + public List getUsers() { + // Map users = userMapper.getUsers(); + // return users.values().toArray(new User[0]); + return userMapper.getUsers(); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 936033f..5681050 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,5 +1,13 @@ -spring.datasource.url=jdbc:sqlite:data -# spring.datasource.driver-class-name=org.sqlite.JDBC +# Setting used by @Repository +spring.datasource.url=jdbc:sqlite:data/mainapp.sqlite3 +spring.datasource.driver-class-name=org.sqlite.JDBC # spring.datasource.username= # spring.datasource.password= -mybatis.config-location=classpath:mybatis/config.xml + +# MyBatis related: +# mybatis.check-config-location=true +# mybatis.mapper-locations=classpath:mapper/*.xml +# mybatis.type-aliases-package=com.badbuta.learnspringbootrestfulsqlite.entities +mybatis.config-location=classpath:mybatis/mybatis-config.xml + +server.port=8888 diff --git a/src/main/resources/mapper/mainapp.xml b/src/main/resources/mapper/mainapp.xml deleted file mode 100644 index 959832c..0000000 --- a/src/main/resources/mapper/mainapp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/main/resources/mapping/UserMapper.xml b/src/main/resources/mapping/UserMapper.xml new file mode 100644 index 0000000..4a939ac --- /dev/null +++ b/src/main/resources/mapping/UserMapper.xml @@ -0,0 +1,29 @@ + + + + + + + + + SELECT last_insert_rowid() + + insert into users (name,password) values (#{name},#{password}) + + + + + + \ No newline at end of file diff --git a/src/main/resources/mybatis/config.xml b/src/main/resources/mybatis/config.xml deleted file mode 100644 index ceb8eab..0000000 --- a/src/main/resources/mybatis/config.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/mybatis/mybatis-config.xml b/src/main/resources/mybatis/mybatis-config.xml new file mode 100644 index 0000000..126119f --- /dev/null +++ b/src/main/resources/mybatis/mybatis-config.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file