BookWell API Implementation and Test
シナリオ
背景: あなたは「BookWell」というオンライン書籍管理システムを開発しています。このシステムは、ユーザーが書籍の情報を追加、取得、更新、削除(CRUD操作)することを可能にします。システムはBasic認証とJWTを使用して、認証と認可を行います。
要件
- Basic認証: 管理者が書籍情報を管理するために、Basic認証を使用してAPIにアクセスする。
- CRUD操作: 書籍の追加、取得、更新、削除が可能なAPIを実装する。
- JWT認証: 一般ユーザーが書籍情報を取得するために、JWT認証を使用する。
問題1: Basic認証を使用したAPIの実装
管理者がBasic認証を使用して書籍情報を管理できるように、以下のAPIエンドポイントを実装してください。
- 書籍の追加 (POST /admin/books)
- 書籍の更新 (PUT /admin/books/{id})
- 書籍の削除 (DELETE /admin/books/{id})
問題2: CRUD操作の実装
一般ユーザーが書籍情報を取得できるように、以下のAPIエンドポイントを実装してください。
- 書籍の取得 (GET /books)
- 書籍の詳細取得 (GET /books/{id})
問題3: JWT認証の実装
一般ユーザーがJWTを使用して認証するための仕組みを実装してください。
- JWTの発行 (POST /auth/login)
- JWTを使用した書籍情報の取得 (GET /books, GET /books/{id})
Java
問題1: Basic認証を使用したAPIの実装
AdminBookController.java
@RestController @RequestMapping("/admin/books") public class AdminBookController { @PostMapping public ResponseEntity<String> addBook(@RequestBody Book book) { // Implement logic to add book return ResponseEntity.ok("Book added successfully"); } @PutMapping("/{id}") public ResponseEntity<String> updateBook(@PathVariable("id") String id, @RequestBody Book book) { // Implement logic to update book return ResponseEntity.ok("Book updated successfully"); } @DeleteMapping("/{id}") public ResponseEntity<String> deleteBook(@PathVariable("id") String id) { // Implement logic to delete book return ResponseEntity.ok("Book deleted successfully"); } }
問題2: CRUD操作の実装
UserController.java
@RestController @RequestMapping("/books") public class UserController { @GetMapping public ResponseEntity<List<Book>> getAllBooks() { // Implement logic to fetch all books return ResponseEntity.ok(Collections.emptyList()); } @GetMapping("/{id}") public ResponseEntity<Book> getBookById(@PathVariable("id") String id) { // Implement logic to fetch book by id return ResponseEntity.ok(new Book()); } }
問題3: JWT認証の実装
AuthController.java
@RestController @RequestMapping("/auth") public class AuthController { @PostMapping("/login") public ResponseEntity<String> login(@RequestBody LoginRequest request) { // Implement login logic and JWT generation String token = generateToken(request.getUsername()); return ResponseEntity.ok(token); } // Method to generate JWT token (example) private String generateToken(String username) { // Implement JWT generation logic return "example_jwt_token"; } }
Node.js (Express)
問題1: Basic認証を使用したAPIの実装
adminRoutes.js
const express = require('express'); const router = express.Router(); // Admin routes router.post('/admin/books', (req, res) => { // Implement logic to add book res.send('Book added successfully'); }); router.put('/admin/books/:id', (req, res) => { // Implement logic to update book res.send('Book updated successfully'); }); router.delete('/admin/books/:id', (req, res) => { // Implement logic to delete book res.send('Book deleted successfully'); }); module.exports = router;
問題2: CRUD操作の実装
userRoutes.js
const express = require('express'); const router = express.Router(); // User routes router.get('/books', (req, res) => { // Implement logic to fetch all books res.json([]); }); router.get('/books/:id', (req, res) => { // Implement logic to fetch book by id res.json({}); }); module.exports = router;
問題3: JWT認証の実装
authRoutes.js
const express = require('express'); const router = express.Router(); const jwt = require('jsonwebtoken'); // Auth routes router.post('/auth/login', (req, res) => { // Implement login logic and JWT generation const token = generateToken(req.body.username); res.send(token); }); // Function to generate JWT token (example) function generateToken(username) { // Implement JWT generation logic return jwt.sign({ username: username }, 'mySecretKey', { expiresIn: '1h' }); } module.exports = router;
Go
問題1: Basic認証を使用したAPIの実装
main.go (Admin routes)
package main import ( "fmt" "log" "net/http" "github.com/gorilla/mux" ) func main() { r := mux.NewRouter() // Admin routes r.HandleFunc("/admin/books", addBook).Methods("POST") r.HandleFunc("/admin/books/{id}", updateBook).Methods("PUT") r.HandleFunc("/admin/books/{id}", deleteBook).Methods("DELETE") log.Fatal(http.ListenAndServe(":8080", r)) } func addBook(w http.ResponseWriter, r *http.Request) { // Implement logic to add book w.Write([]byte("Book added successfully\n")) } func updateBook(w http.ResponseWriter, r *http.Request) { // Implement logic to update book vars := mux.Vars(r) id := vars["id"] w.Write([]byte(fmt.Sprintf("Book %s updated successfully\n", id))) } func deleteBook(w http.ResponseWriter, r *http.Request) { // Implement logic to delete book vars := mux.Vars(r) id := vars["id"] w.Write([]byte(fmt.Sprintf("Book %s deleted successfully\n", id))) }
問題2: CRUD操作の実装
main.go (User routes)
package main import ( "encoding/json" "net/http" "github.com/gorilla/mux" ) type Book struct { ID string `json:"id"` Title string `json:"title"` Author string `json:"author"` } func main() { r := mux.NewRouter() // User routes r.HandleFunc("/books", getAllBooks).Methods("GET") r.HandleFunc("/books/{id}", getBookById).Methods("GET") log.Fatal(http.ListenAndServe(":8080", r)) } func getAllBooks(w http.ResponseWriter, r *http.Request) { // Implement logic to fetch all books books := []Book{} json.NewEncoder(w).Encode(books) } func getBookById(w http.ResponseWriter, r *http.Request) { // Implement logic to fetch book by id params := mux.Vars(r) id := params["id"] book := Book{ID: id, Title: "Book Title", Author: "Author Name"} json.NewEncoder(w).Encode(book) }
問題3: JWT認証の実装
main.go (Auth routes)
package main import ( "net/http" "github.com/gorilla/mux" ) func main() { r := mux.NewRouter() // Auth routes r.HandleFunc("/auth/login", login).Methods("POST") log.Fatal(http.ListenAndServe(":8080", r)) } func login(w http.ResponseWriter, r *http.Request) { // Implement login logic and JWT generation // Dummy JWT token generation token := "example_jwt_token" w.Write([]byte(token)) }
テスト用Curlコマンドスクリプト (test.sh)
#!/bin/bash echo "Testing Basic Authentication for admin endpoints" # Basic Authentication for admin echo "Adding a book as admin..." curl -u admin:password -X POST <http://localhost:8080/admin/books> -d '{"title":"Book Title","author":"Author Name"}' -H "Content-Type: application/json" echo "" echo "Updating a book as admin..." curl -u admin:password -X PUT <http://localhost:8080/admin/books/1> -d '{"title":"Updated Book Title","author":"Author Name"}' -H "Content-Type: application/json" echo "" echo "Deleting a book as admin..." curl -u admin:password -X DELETE <http://localhost:8080/admin/books/1> echo "" echo "Testing JWT Authentication for user endpoints" # JWT Authentication for user echo "Logging in as user to get JWT token..." TOKEN=$(curl -s -X POST <http://localhost:8080/auth/login> -d '{"username":"user","password":"password"}') echo "Token received: $TOKEN" echo "" echo "Fetching all books as user..." curl -H "Authorization: Bearer $TOKEN" <http://localhost:8080/books> echo "" echo "Fetching a book by ID as user..." curl -H "Authorization: Bearer $TOKEN" <http://localhost:8080/books/1> echo ""
追加問題: EC2インスタンスでの公開
NginxまたはApacheを使用して、BookWell APIをEC2インスタンス上で公開してください。
要件
- EC2インスタンスの作成: AWS EC2インスタンスを作成し、必要なセキュリティグループ設定を行う。
- Webサーバーの設定: NginxまたはApacheをインストールし、APIアプリケーションを公開するための設定を行う。
- APIのデプロイ: BookWell APIアプリケーションをEC2インスタンス上にデプロイする。
- 公開とテスト: EC2インスタンスのパブリックIPアドレスを使用して、APIが公開されていることを確認する。
追加問題2: データベース操作の実装
BookWell APIにデータベース操作を追加し、書籍情報をデータベースに保存、更新、削除する機能を実装してください。
要件
- データベースの設定: PostgreSQLやMySQLなどのリレーショナルデータベースを使用してデータベースを設定する。
- データベース接続の実装: APIアプリケーションにデータベース接続を実装する。
- データベース操作の追加: 書籍情報の追加、取得、更新、削除をデータベースに対して行う機能を実装する。
エンドポイント
- 書籍の追加 (POST /admin/books)
- 書籍の取得 (GET /books)
- 書籍の詳細取得 (GET /books/{id})
- 書籍の更新 (PUT /admin/books/{id})
- 書籍の削除 (DELETE /admin/books/{id})