TanmoySG / wunderDB

A micro JSON-based Data Store inspired by MongoDB.
http://wdb.tanmoysg.com/api/
Apache License 2.0
13 stars 0 forks source link

[Design] Server Interaction - Endpoints, HTTP Verbs and Request Body/Arguments #19

Closed TanmoySG closed 1 year ago

TanmoySG commented 1 year ago

While building the server components we need to decide how the endpoints are to created.

TanmoySG commented 1 year ago
TanmoySG commented 1 year ago
TanmoySG commented 1 year ago

Guide - How SQL Server can be converted to REST API?

https://medium.com/voobans-tech-stories/how-to-quickly-create-a-simple-rest-api-for-sql-server-database-7ddb595f751a

TanmoySG commented 1 year ago

Additional Read

TanmoySG commented 1 year ago

Reads

TanmoySG commented 1 year ago

HTTP Status Codes

TanmoySG commented 1 year ago

Endpoints and HTTP Verbs

The following endpoints "might" be used for interaction with WDB.

Database

  1. Add Database
POST  /api/databases

BODY  { name, config }
  1. Fetch Database
GET  /api/databases/{database-name}
  1. Delete Database
DELETE  /api/databases/{database-name}

Collection

  1. Add Collection
POST  /api/databases/{database-name}/collections

BODY  { name, config }
  1. Fetch Collection
GET  /api/databases/{database-name}/collections/{collection-name}
  1. Delete Collection
DELETE  /api/databases/{database-name}/collections/{collection-name}
TanmoySG commented 1 year ago

Endpoints and HTTP Verbs

The following endpoints "might" be used for interaction with WDB.

Note : Passing the filters is not yet finalized - how it'll be passed.

Data

  1. Put Data
POST/PUT  /api/databases/{db-name}/collections/{collection-name}/data

BODY  { data }
  1. Fetch Data
GET  /api/databases/{db-name}/collections/{collection-name}/data?key=<key>&value=<value>
  1. Delete Data
DELETE  /api/databases/{db-name}/collections/{collection-name}/data?filters={key: <key>, value: <value>}
  1. Update Data
PATCH  /api/databases/{db-name}/collections/{collection-name}/data?filters={key: <key>, value: <value>}

BODY  { data, only fields to update }
TanmoySG commented 1 year ago

HTTP Verbs

https://www.restapitutorial.com/lessons/httpmethods.html

TanmoySG commented 1 year ago

API Response

TanmoySG commented 1 year ago

API Response

API Response structure for any action.

{
    "action" : "what was performed",
    "status" : "success/failure",
    "errors" : {
        "code" : "",
        "stack" : [ ]
    },
    "data" : { }
}
TanmoySG commented 1 year ago

Query JSON with JSONPath

Patching JSON with JSONPatch

TanmoySG commented 1 year ago

API Specs

OpenAPI Spec YAML ```yml openapi: 3.0.0 info: title: wdbv2 version: 1.0.0 servers: - url: http://{{url}} - url: localhost:// components: securitySchemes: basicAuth: type: http scheme: basic security: - basicAuth: [] tags: - name: Users - name: Roles - name: Databases - name: Collections - name: Data paths: /api/users: post: tags: - Users summary: Create Users requestBody: content: application/json: schema: type: object example: '' security: - basicAuth: [] responses: '200': description: Successful response content: application/json: {} /api/users/grant: post: tags: - Users summary: Grant Role requestBody: content: application/json: schema: type: object example: username: random-user permissions: role: roleOne 'on': databases: '*' responses: '200': description: Successful response content: application/json: {} /api/users/permission: get: tags: - Users summary: Check Permissions parameters: - name: privilege in: query schema: type: string example: createRole responses: '200': description: Successful response content: application/json: {} /000/api/roles: post: tags: - Roles summary: Create Role requestBody: content: application/json: schema: type: object example: role: roleY allowed: - createDatabase - grantRole - createRole - listRole denied: - addData responses: '200': description: Successful response content: application/json: {} /api/roles: get: tags: - Roles summary: List Roles parameters: - name: Accept in: header schema: type: string example: application/json responses: '200': description: Successful response content: application/json: {} /000/api/databases: post: tags: - Databases summary: Create Database requestBody: content: application/json: schema: type: object example: name: test-db-001 responses: '200': description: Successful response content: application/json: {} /api/databases/{database}: get: tags: - Databases summary: Get Database parameters: - name: database in: path schema: type: string required: true responses: '200': description: Successful response content: application/json: {} delete: tags: - Databases summary: Delete Database parameters: - name: database in: path schema: type: string required: true responses: '200': description: Successful response content: application/json: {} /api/databases/{database}/collections: post: tags: - Collections summary: Create Collection requestBody: content: application/json: schema: type: object example: name: test-coll-001 schema: type: object properties: name: type: string age: type: integer required: - name - age parameters: - name: database in: path schema: type: string required: true example: test-db-001 responses: '200': description: Successful response content: application/json: {} /api/databases/{database}/collections/{collection}: get: tags: - Collections summary: Get Collection parameters: - name: database in: path schema: type: string required: true - name: collection in: path schema: type: string required: true responses: '200': description: Successful response content: application/json: {} delete: tags: - Collections summary: Delete Collection parameters: - name: database in: path schema: type: string required: true - name: collection in: path schema: type: string required: true responses: '200': description: Successful response content: application/json: {} /api/databases/{database}/collections/{collection}/data: post: tags: - Data summary: Add Data requestBody: content: application/json: schema: type: object example: name: tfds age: 28 parameters: - name: database in: path schema: type: string required: true example: test-db-001 - name: collection in: path schema: type: string required: true example: test-coll-001 responses: '200': description: Successful response content: application/json: {} get: tags: - Data summary: Get Data parameters: - name: database in: path schema: type: string required: true example: test-db-001 - name: collection in: path schema: type: string required: true example: test-coll-001 responses: '200': description: Successful response content: application/json: {} delete: tags: - Data summary: Delete Data parameters: - name: key in: query schema: type: string example: age - name: value in: query schema: type: integer example: '23' - name: database in: path schema: type: string required: true example: test-db-001 - name: collection in: path schema: type: string required: true example: test-coll-001 responses: '200': description: Successful response content: application/json: {} patch: tags: - Data summary: Update Data requestBody: content: application/json: schema: type: object example: age: 69 parameters: - name: key in: query schema: type: string example: age - name: value in: query schema: type: integer example: '28' - name: database in: path schema: type: string required: true example: test-db-001 - name: collection in: path schema: type: string required: true example: test-coll-001 responses: '200': description: Successful response content: application/json: {} /api: get: tags: - default summary: Hello responses: '200': description: OK content: text/plain: schema: type: string example: ✋ hello ```
Postman Collection JSON ```json { "info": { "_postman_id": "259a76cc-c479-41a8-b639-669753c63684", "name": "wdbv2", "schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json", "_exporter_id": "15618820" }, "item": [ { "name": "Users", "item": [ { "name": "Create Users", "request": { "auth": { "type": "basic", "basic": { "username": "test-user55", "password": "admin" } }, "method": "POST", "header": [], "body": { "mode": "raw", "raw": "", "options": { "raw": { "language": "json" } } }, "url": "{{URL}}/api/users" }, "response": [] }, { "name": "Grant Role", "request": { "method": "POST", "header": [], "body": { "mode": "raw", "raw": "{\n \"username\": \"random-user\",\n \"permissions\": {\n \"role\": \"roleOne\",\n \"on\": {\n \"databases\": \"*\"\n }\n }\n}", "options": { "raw": { "language": "json" } } }, "url": "{{URL}}/api/users/grant" }, "response": [] }, { "name": "Check Permissions", "request": { "method": "GET", "header": [], "url": { "raw": "{{URL}}/api/users/permission?privilege=createRole", "host": [ "{{URL}}" ], "path": [ "api", "users", "permission" ], "query": [ { "key": "privilege", "value": "createRole" } ] } }, "response": [] } ] }, { "name": "Roles", "item": [ { "name": "Create Role", "request": { "method": "POST", "header": [], "body": { "mode": "raw", "raw": "{\n \"role\": \"roleY\",\n \"allowed\": [\n \"createDatabase\",\n \"grantRole\",\n \"createRole\",\n \"listRole\"\n ],\n \"denied\": [\n \"addData\"\n ]\n}", "options": { "raw": { "language": "json" } } }, "url": "localhost:3000/api/roles" }, "response": [] }, { "name": "List Roles", "protocolProfileBehavior": { "disabledSystemHeaders": { "accept": true } }, "request": { "method": "GET", "header": [ { "key": "Accept", "value": "application/json", "type": "text" } ], "url": "{{URL}}/api/roles" }, "response": [] } ] }, { "name": "Databases", "item": [ { "name": "Create Database", "request": { "method": "POST", "header": [], "body": { "mode": "raw", "raw": "{\n \"name\" : \"test-db-001\"\n}", "options": { "raw": { "language": "json" } } }, "url": "localhost:3000/api/databases" }, "response": [] }, { "name": "Get Database", "request": { "method": "GET", "header": [], "url": { "raw": "{{URL}}/api/databases/:database", "host": [ "{{URL}}" ], "path": [ "api", "databases", ":database" ], "variable": [ { "key": "database", "value": "" } ] } }, "response": [] }, { "name": "Delete Database", "request": { "method": "DELETE", "header": [], "url": { "raw": "{{URL}}/api/databases/:database", "host": [ "{{URL}}" ], "path": [ "api", "databases", ":database" ], "variable": [ { "key": "database", "value": null } ] } }, "response": [] } ] }, { "name": "Collections", "item": [ { "name": "Create Collection", "request": { "method": "POST", "header": [], "body": { "mode": "raw", "raw": "{\n \"name\": \"test-coll-001\",\n \"schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"age\": {\n \"type\": \"integer\"\n }\n },\n \"required\": [\n \"name\",\n \"age\"\n ]\n }\n}", "options": { "raw": { "language": "json" } } }, "url": { "raw": "{{URL}}/api/databases/:database/collections", "host": [ "{{URL}}" ], "path": [ "api", "databases", ":database", "collections" ], "variable": [ { "key": "database", "value": "test-db-001" } ] } }, "response": [] }, { "name": "Get Collection", "request": { "method": "GET", "header": [], "url": { "raw": "{{URL}}/api/databases/:database/collections/:collection", "host": [ "{{URL}}" ], "path": [ "api", "databases", ":database", "collections", ":collection" ], "variable": [ { "key": "database", "value": null }, { "key": "collection", "value": null } ] } }, "response": [] }, { "name": "Delete Collection", "request": { "method": "DELETE", "header": [], "url": { "raw": "{{URL}}/api/databases/:database/collections/:collection", "host": [ "{{URL}}" ], "path": [ "api", "databases", ":database", "collections", ":collection" ], "variable": [ { "key": "database", "value": null }, { "key": "collection", "value": null } ] } }, "response": [] } ] }, { "name": "Data", "item": [ { "name": "Add Data", "request": { "method": "POST", "header": [], "body": { "mode": "raw", "raw": "{\n \"name\": \"tfds\",\n \"age\": 28\n}", "options": { "raw": { "language": "json" } } }, "url": { "raw": "{{URL}}/api/databases/:database/collections/:collection/data", "host": [ "{{URL}}" ], "path": [ "api", "databases", ":database", "collections", ":collection", "data" ], "variable": [ { "key": "database", "value": "test-db-001" }, { "key": "collection", "value": "test-coll-001" } ] } }, "response": [] }, { "name": "Get Data", "request": { "method": "GET", "header": [], "url": { "raw": "{{URL}}/api/databases/:database/collections/:collection/data", "host": [ "{{URL}}" ], "path": [ "api", "databases", ":database", "collections", ":collection", "data" ], "query": [ { "key": "key", "value": "age", "disabled": true }, { "key": "value", "value": "23", "disabled": true } ], "variable": [ { "key": "database", "value": "test-db-001" }, { "key": "collection", "value": "test-coll-001" } ] } }, "response": [] }, { "name": "Delete Data", "request": { "method": "DELETE", "header": [], "url": { "raw": "{{URL}}/api/databases/:database/collections/:collection/data?key=age&value=23", "host": [ "{{URL}}" ], "path": [ "api", "databases", ":database", "collections", ":collection", "data" ], "query": [ { "key": "key", "value": "age" }, { "key": "value", "value": "23" } ], "variable": [ { "key": "database", "value": "test-db-001" }, { "key": "collection", "value": "test-coll-001" } ] } }, "response": [] }, { "name": "Update Data", "request": { "method": "PATCH", "header": [], "body": { "mode": "raw", "raw": "{\n \"age\": 69\n}", "options": { "raw": { "language": "json" } } }, "url": { "raw": "{{URL}}/api/databases/:database/collections/:collection/data?key=age&value=28", "host": [ "{{URL}}" ], "path": [ "api", "databases", ":database", "collections", ":collection", "data" ], "query": [ { "key": "key", "value": "age" }, { "key": "value", "value": "28" } ], "variable": [ { "key": "database", "value": "test-db-001" }, { "key": "collection", "value": "test-coll-001" } ] } }, "response": [] } ] }, { "name": "Hello", "request": { "method": "GET", "header": [], "url": "{{URL}}/api" }, "response": [ { "name": "Hello", "originalRequest": { "method": "GET", "header": [], "url": "{{URL}}/api" }, "status": "OK", "code": 200, "_postman_previewlanguage": null, "header": null, "cookie": [], "body": "✋ hello" } ] } ], "auth": { "type": "basic", "basic": { "password": "wowpwd", "username": "admin" } }, "event": [ { "listen": "prerequest", "script": { "type": "text/javascript", "exec": [ "" ] } }, { "listen": "test", "script": { "type": "text/javascript", "exec": [ "" ] } } ], "variable": [ { "key": "URL", "value": "localhost:8086", "type": "string" } ] } ```