0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

NestJSをAPI Gateway + AWS Lambdaで構成する(その3)- Controllersコントローラー

Last updated at Posted at 2023-07-24

Controllers(コントローラー)

公式

コントロールはざっくり

  • サーバー側としてHttp リクエストを処理する起点となるところ
  • リクエストされるURLの部分と処理するclassを紐付けるのはNestJSのフレームワーク側でやってくれる

aws-node-typescript-nest/src/app.controller.tsをみてみると、

aws-node-typescript-nest/src/app.controller.ts
@Controller()
export class AppController {
  constructor(private readonly appService: AppService) { }

  @Get('hello')
  getHello(): string {
    return this.appService.getHello();
  }
}
  • @Get('hello')http://localhost:3000/hello にマッピングされる
  • /hello にリクエストがきたら、@Get('hello') を指定する getHello() が動作する

Get, Post リクエスト

  • @Get('hello') は Getメソッドリクエスト対応なので、http://localhost:3000/hello に対して Postメソッドリクエストを送ると対応するHttpメソッドがないため404になります。

404 Not Foundの場合のレスポンス

{
    "statusCode": 404,
    "error": "Not Found",
    "message": "Cannot POST /hello"
}

serverless.yml では、 methdoはanyなのでGetでもPostでも受付る

aws-node-typescript-nest/serverless.yml
functions:
  main:
    handler: src/main.handler
    events:
      - http:
          method: any
          path: /{proxy+}
  • Postメソッドリクエストで動作するようにするには、以下のようにすれば良い
  @Post('hello')
  getHello(): string {
    return this.appService.getHello();
  }

コントローラーの追加

usage:

$ nest g controller [コントローラー名]

実行例

nest g controller cats

以下が生成される

  • src/cats/cats.controller.ts
  • src/cats/cats.controller.spec.ts ←テスト用ファイル

以下が更新される、追加した catsがmoduleに追加され リクエストを受けるエンドポイントとして認識されるようになる
src/app.module.ts

...
import { CatsController } from './cats/cats.controller';

...

@Module({
  imports: [],
  controllers: [AppController, CatsController],
  providers: [AppService],
})
export class AppModule {}

追加したコントローラーにリクエストを送る

リクエスト

$ curl -X "GET"  http://localhost:3000/dev/cats

レスポンス

This action returns all cats
  • 末尾のスラッシュ有無では違いなし
$ curl -X "GET"  http://localhost:3000/dev/cats
$ curl -X "GET"  http://localhost:3000/dev/cats/

追加したコントローラーにリクエストパラメータ付きのリクエストを送る

a=1というパラメータをつける

  • CatsControllerでは、console.log({ request }); を追加してログを出力する
$ curl -X "GET"  http://localhost:3000/dev/cats/?a=1
  • console.logの内容を確認
[Nest] 2014   - 7/19/2023, 1:07:29 PM   [NestApplication] Nest application successfully started +1ms
{
  request: <ref *1> IncomingMessage {
    _readableState: ReadableState {
      objectMode: false,
      highWaterMark: 16384,
      buffer: BufferList { head: null, tail: null, length: 0 },
      length: 0,
      pipes: [],
      flowing: null,
      ended: true,
      endEmitted: false,
      reading: false,
      constructed: true,
      sync: true,
      needReadable: false,
      emittedReadable: false,
      readableListening: false,
      resumeScheduled: false,
      errorEmitted: false,
      emitClose: true,
      autoDestroy: true,
      destroyed: false,
      errored: null,
      closed: false,
      closeEmitted: false,
      defaultEncoding: 'utf8',
      awaitDrainWriters: null,
      multiAwaitDrain: false,
      readingMore: true,
      dataEmitted: false,
      decoder: null,
      encoding: null,
      [Symbol(kPaused)]: null
    },
    _events: [Object: null prototype] { end: [Function: clearRequestTimeout] },
    _eventsCount: 1,
    _maxListeners: undefined,
    socket: Socket {
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: null,
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 8,
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: true,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: [Server],
      _server: [Server],
      parser: [HTTPParser],
      on: [Function: socketListenerWrap],
      addListener: [Function: socketListenerWrap],
      prependListener: [Function: socketListenerWrap],
      setEncoding: [Function: socketSetEncoding],
      _paused: false,
      _httpMessage: [ServerResponse],
      [Symbol(async_id_symbol)]: 29,
      [Symbol(kHandle)]: [Pipe],
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kSetNoDelay)]: false,
      [Symbol(kSetKeepAlive)]: false,
      [Symbol(kSetKeepAliveInitialDelay)]: 0,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(RequestTimeout)]: undefined
    },
    httpVersionMajor: 1,
    httpVersionMinor: 1,
    httpVersion: '1.1',
    complete: true,
    rawHeaders: [
      'Host',
      'localhost:3000',
      'User-Agent',
      'curl/7.74.0',
      'Accept',
      '*/*',
      'x-apigateway-event',
      '%7B%22headers%22%3A%7B%22Host%22%3A%22localhost%3A3000%22%2C%22User-Agent%22%3A%22curl%2F7.74.0%22%2C%22Accept%22%3A%22*%2F*%22%7D%2C%22httpMethod%22%3A%22GET%22%2C%22isBase64Encoded%22%3Afalse%2C%22multiValueHeaders%22%3A%7B%22Host%22%3A%5B%22localhost%3A3000%22%5D%2C%22User-Agent%22%3A%5B%22curl%2F7.74.0%22%5D%2C%22Accept%22%3A%5B%22*%2F*%22%5D%7D%2C%22multiValueQueryStringParameters%22%3A%7B%22a%22%3A%5B%221%22%5D%7D%2C%22path%22%3A%22%2Fcats%22%2C%22pathParameters%22%3A%7B%22proxy%22%3A%22cats%22%7D%2C%22queryStringParameters%22%3A%7B%22a%22%3A%221%22%7D%2C%22requestContext%22%3A%7B%22accountId%22%3A%22offlineContext_accountId%22%2C%22apiId%22%3A%22offlineContext_apiId%22%2C%22authorizer%22%3A%7B%22principalId%22%3A%22offlineContext_authorizer_principalId%22%7D%2C%22domainName%22%3A%22offlineContext_domainName%22%2C%22domainPrefix%22%3A%22offlineContext_domainPrefix%22%2C%22extendedRequestId%22%3A%22b411061f-de1b-4be9-a6a4-a982476a36bf%22%2C%22httpMethod%22%3A%22GET%22%2C%22identity%22%3A%7B%22accessKey%22%3Anull%2C%22accountId%22%3A%22offlineContext_accountId%22%2C%22apiKey%22%3A%22offlineContext_apiKey%22%2C%22apiKeyId%22%3A%22offlineContext_apiKeyId%22%2C%22caller%22%3A%22offlineContext_caller%22%2C%22cognitoAuthenticationProvider%22%3A%22offlineContext_cognitoAuthenticationProvider%22%2C%22cognitoAuthenticationType%22%3A%22offlineContext_cognitoAuthenticationType%22%2C%22cognitoIdentityId%22%3A%22offlineContext_cognitoIdentityId%22%2C%22cognitoIdentityPoolId%22%3A%22offlineContext_cognitoIdentityPoolId%22%2C%22principalOrgId%22%3Anull%2C%22sourceIp%22%3A%22127.0.0.1%22%2C%22user%22%3A%22offlineContext_user%22%2C%22userAgent%22%3A%22curl%2F7.74.0%22%2C%22userArn%22%3A%22offlineContext_userArn%22%7D%2C%22path%22%3A%22%2Fcats%22%2C%22protocol%22%3A%22HTTP%2F1.1%22%2C%22requestId%22%3A%2292886438-c883-471c-859b-86b9fa2434ab%22%2C%22requestTime%22%3A%2219%2FJul%2F2023%3A13%3A07%3A28%20%2B0000%22%2C%22requestTimeEpoch%22%3A1689772048766%2C%22resourceId%22%3A%22offlineContext_resourceId%22%2C%22resourcePath%22%3A%22%2Fdev%2F%7Bproxy*%7D%22%2C%22stage%22%3A%22dev%22%7D%2C%22resource%22%3A%22%2F%7Bproxy%2B%7D%22%2C%22stageVariables%22%3Anull%7D',
      'x-apigateway-context',
      '%7B%22awsRequestId%22%3A%224e598571-6fa8-45fa-b8c3-0d0b5263a1a1%22%2C%22callbackWaitsForEmptyEventLoop%22%3Atrue%2C%22clientContext%22%3Anull%2C%22functionName%22%3A%22serverless-nest-example-dev-main%22%2C%22functionVersion%22%3A%22%24LATEST%22%2C%22invokedFunctionArn%22%3A%22offline_invokedFunctionArn_for_serverless-nest-example-dev-main%22%2C%22logGroupName%22%3A%22offline_logGroupName_for_serverless-nest-example-dev-main%22%2C%22logStreamName%22%3A%22offline_logStreamName_for_serverless-nest-example-dev-main%22%2C%22memoryLimitInMB%22%3A%221024%22%7D',
      'Connection',
      'close'
    ],
    rawTrailers: [],
    aborted: false,
    upgrade: false,
    url: '/cats?a=1',
    method: 'GET',
    statusCode: null,
    statusMessage: null,
    client: Socket {
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: null,
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 8,
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: true,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: [Server],
      _server: [Server],
      parser: [HTTPParser],
      on: [Function: socketListenerWrap],
      addListener: [Function: socketListenerWrap],
      prependListener: [Function: socketListenerWrap],
      setEncoding: [Function: socketSetEncoding],
      _paused: false,
      _httpMessage: [ServerResponse],
      [Symbol(async_id_symbol)]: 29,
      [Symbol(kHandle)]: [Pipe],
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kSetNoDelay)]: false,
      [Symbol(kSetKeepAlive)]: false,
      [Symbol(kSetKeepAliveInitialDelay)]: 0,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(RequestTimeout)]: undefined
    },
    _consuming: false,
    _dumped: false,
    next: [Function: next],
    baseUrl: '',
    originalUrl: '/cats?a=1',
    _parsedUrl: Url {
      protocol: null,
      slashes: null,
      auth: null,
      host: null,
      port: null,
      hostname: null,
      hash: null,
      search: '?a=1',
      query: 'a=1',
      pathname: '/cats',
      path: '/cats?a=1',
      href: '/cats?a=1',
      _raw: '/cats?a=1'
    },
    params: {},
    query: { a: '1' },
    res: ServerResponse {
      _events: [Object: null prototype],
      _eventsCount: 1,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      destroyed: false,
      _last: false,
      chunkedEncoding: false,
      shouldKeepAlive: false,
      maxRequestsOnConnectionReached: false,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: true,
      sendDate: true,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      _contentLength: null,
      _hasBody: true,
      _trailer: '',
      finished: false,
      _headerSent: false,
      _closed: false,
      socket: [Socket],
      _header: null,
      _keepAliveTimeout: 5000,
      _onPendingData: [Function: bound updateOutgoingData],
      req: [Circular *1],
      _sent100: false,
      _expect_continue: false,
      locals: [Object: null prototype] {},
      [Symbol(kCapture)]: false,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype],
      [Symbol(kUniqueHeaders)]: null
    },
    apiGateway: { event: [Object], context: [Object] },
    body: {},
    route: Route { path: '/cats', stack: [Array], methods: [Object] },
    [Symbol(kCapture)]: false,
    [Symbol(kHeaders)]: {
      host: 'localhost:3000',
      'user-agent': 'curl/7.74.0',
      accept: '*/*',
      connection: 'close'
    },
    [Symbol(kHeadersCount)]: 12,
    [Symbol(kTrailers)]: null,
    [Symbol(kTrailersCount)]: 0,
    [Symbol(RequestTimeout)]: undefined
  }
}
(λ: main) RequestId: 4e598571-6fa8-45fa-b8c3-0d0b5263a1a1  Duration: 271.70 ms  Billed Duration: 272 ms

a=あいうえお というパラメータをつける

  • リクエストする時にはURLエンコードを行う
$ curl -G http://localhost:3000/dev/cats/ --data-urlencode "a=あいうえお"
  • console.logの内容を確認
ANY /dev/cats (λ: main)
{
  request: <ref *1> IncomingMessage {
    _readableState: ReadableState {
      objectMode: false,
      highWaterMark: 16384,
      buffer: BufferList { head: null, tail: null, length: 0 },
      length: 0,
      pipes: [],
      flowing: null,
      ended: true,
      endEmitted: false,
      reading: false,
      constructed: true,
      sync: true,
      needReadable: false,
      emittedReadable: false,
      readableListening: false,
      resumeScheduled: false,
      errorEmitted: false,
      emitClose: true,
      autoDestroy: true,
      destroyed: false,
      errored: null,
      closed: false,
      closeEmitted: false,
      defaultEncoding: 'utf8',
      awaitDrainWriters: null,
      multiAwaitDrain: false,
      readingMore: true,
      dataEmitted: false,
      decoder: null,
      encoding: null,
      [Symbol(kPaused)]: null
    },
    _events: [Object: null prototype] { end: [Function: clearRequestTimeout] },
    _eventsCount: 1,
    _maxListeners: undefined,
    socket: Socket {
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: null,
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 8,
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: true,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: [Server],
      _server: [Server],
      parser: [HTTPParser],
      on: [Function: socketListenerWrap],
      addListener: [Function: socketListenerWrap],
      prependListener: [Function: socketListenerWrap],
      setEncoding: [Function: socketSetEncoding],
      _paused: false,
      _httpMessage: [ServerResponse],
      [Symbol(async_id_symbol)]: 159,
      [Symbol(kHandle)]: [Pipe],
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kSetNoDelay)]: false,
      [Symbol(kSetKeepAlive)]: false,
      [Symbol(kSetKeepAliveInitialDelay)]: 0,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(RequestTimeout)]: undefined
    },
    httpVersionMajor: 1,
    httpVersionMinor: 1,
    httpVersion: '1.1',
    complete: true,
    rawHeaders: [
      'Host',
      'localhost:3000',
      'User-Agent',
      'curl/7.74.0',
      'Accept',
      '*/*',
      'x-apigateway-event',
      '%7B%22headers%22%3A%7B%22Host%22%3A%22localhost%3A3000%22%2C%22User-Agent%22%3A%22curl%2F7.74.0%22%2C%22Accept%22%3A%22*%2F*%22%7D%2C%22httpMethod%22%3A%22GET%22%2C%22isBase64Encoded%22%3Afalse%2C%22multiValueHeaders%22%3A%7B%22Host%22%3A%5B%22localhost%3A3000%22%5D%2C%22User-Agent%22%3A%5B%22curl%2F7.74.0%22%5D%2C%22Accept%22%3A%5B%22*%2F*%22%5D%7D%2C%22multiValueQueryStringParameters%22%3A%7B%22a%22%3A%5B%22%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A%22%5D%7D%2C%22path%22%3A%22%2Fcats%22%2C%22pathParameters%22%3A%7B%22proxy%22%3A%22cats%22%7D%2C%22queryStringParameters%22%3A%7B%22a%22%3A%22%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A%22%7D%2C%22requestContext%22%3A%7B%22accountId%22%3A%22offlineContext_accountId%22%2C%22apiId%22%3A%22offlineContext_apiId%22%2C%22authorizer%22%3A%7B%22principalId%22%3A%22offlineContext_authorizer_principalId%22%7D%2C%22domainName%22%3A%22offlineContext_domainName%22%2C%22domainPrefix%22%3A%22offlineContext_domainPrefix%22%2C%22extendedRequestId%22%3A%22c264f026-ebf6-4d0c-9163-34e44e3de765%22%2C%22httpMethod%22%3A%22GET%22%2C%22identity%22%3A%7B%22accessKey%22%3Anull%2C%22accountId%22%3A%22offlineContext_accountId%22%2C%22apiKey%22%3A%22offlineContext_apiKey%22%2C%22apiKeyId%22%3A%22offlineContext_apiKeyId%22%2C%22caller%22%3A%22offlineContext_caller%22%2C%22cognitoAuthenticationProvider%22%3A%22offlineContext_cognitoAuthenticationProvider%22%2C%22cognitoAuthenticationType%22%3A%22offlineContext_cognitoAuthenticationType%22%2C%22cognitoIdentityId%22%3A%22offlineContext_cognitoIdentityId%22%2C%22cognitoIdentityPoolId%22%3A%22offlineContext_cognitoIdentityPoolId%22%2C%22principalOrgId%22%3Anull%2C%22sourceIp%22%3A%22127.0.0.1%22%2C%22user%22%3A%22offlineContext_user%22%2C%22userAgent%22%3A%22curl%2F7.74.0%22%2C%22userArn%22%3A%22offlineContext_userArn%22%7D%2C%22path%22%3A%22%2Fcats%22%2C%22protocol%22%3A%22HTTP%2F1.1%22%2C%22requestId%22%3A%222acb3594-7a11-439a-a451-7bd8478e84c6%22%2C%22requestTime%22%3A%2219%2FJul%2F2023%3A13%3A21%3A44%20%2B0000%22%2C%22requestTimeEpoch%22%3A1689772904950%2C%22resourceId%22%3A%22offlineContext_resourceId%22%2C%22resourcePath%22%3A%22%2Fdev%2F%7Bproxy*%7D%22%2C%22stage%22%3A%22dev%22%7D%2C%22resource%22%3A%22%2F%7Bproxy%2B%7D%22%2C%22stageVariables%22%3Anull%7D',
      'x-apigateway-context',
      '%7B%22awsRequestId%22%3A%228ef4d650-7c2f-4c57-ba0b-9504e0160346%22%2C%22callbackWaitsForEmptyEventLoop%22%3Atrue%2C%22clientContext%22%3Anull%2C%22functionName%22%3A%22serverless-nest-example-dev-main%22%2C%22functionVersion%22%3A%22%24LATEST%22%2C%22invokedFunctionArn%22%3A%22offline_invokedFunctionArn_for_serverless-nest-example-dev-main%22%2C%22logGroupName%22%3A%22offline_logGroupName_for_serverless-nest-example-dev-main%22%2C%22logStreamName%22%3A%22offline_logStreamName_for_serverless-nest-example-dev-main%22%2C%22memoryLimitInMB%22%3A%221024%22%7D',
      'Connection',
      'close'
    ],
    rawTrailers: [],
    aborted: false,
    upgrade: false,
    url: '/cats?a=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A',
    method: 'GET',
    statusCode: null,
    statusMessage: null,
    client: Socket {
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: null,
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 8,
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: true,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: [Server],
      _server: [Server],
      parser: [HTTPParser],
      on: [Function: socketListenerWrap],
      addListener: [Function: socketListenerWrap],
      prependListener: [Function: socketListenerWrap],
      setEncoding: [Function: socketSetEncoding],
      _paused: false,
      _httpMessage: [ServerResponse],
      [Symbol(async_id_symbol)]: 159,
      [Symbol(kHandle)]: [Pipe],
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kSetNoDelay)]: false,
      [Symbol(kSetKeepAlive)]: false,
      [Symbol(kSetKeepAliveInitialDelay)]: 0,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(RequestTimeout)]: undefined
    },
    _consuming: false,
    _dumped: false,
    next: [Function: next],
    baseUrl: '',
    originalUrl: '/cats?a=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A',
    _parsedUrl: Url {
      protocol: null,
      slashes: null,
      auth: null,
      host: null,
      port: null,
      hostname: null,
      hash: null,
      search: '?a=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A',
      query: 'a=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A',
      pathname: '/cats',
      path: '/cats?a=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A',
      href: '/cats?a=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A',
      _raw: '/cats?a=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A'
    },
    params: {},
    query: { a: 'あいうえお' },
    res: ServerResponse {
      _events: [Object: null prototype],
      _eventsCount: 1,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      destroyed: false,
      _last: false,
      chunkedEncoding: false,
      shouldKeepAlive: false,
      maxRequestsOnConnectionReached: false,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: true,
      sendDate: true,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      _contentLength: null,
      _hasBody: true,
      _trailer: '',
      finished: false,
      _headerSent: false,
      _closed: false,
      socket: [Socket],
      _header: null,
      _keepAliveTimeout: 5000,
      _onPendingData: [Function: bound updateOutgoingData],
      req: [Circular *1],
      _sent100: false,
      _expect_continue: false,
      locals: [Object: null prototype] {},
      [Symbol(kCapture)]: false,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype],
      [Symbol(kUniqueHeaders)]: null
    },
    apiGateway: { event: [Object], context: [Object] },
    body: {},
    route: Route { path: '/cats', stack: [Array], methods: [Object] },
    [Symbol(kCapture)]: false,
    [Symbol(kHeaders)]: {
      host: 'localhost:3000',
      'user-agent': 'curl/7.74.0',
      accept: '*/*',
      connection: 'close'
    },
    [Symbol(kHeadersCount)]: 12,
    [Symbol(kTrailers)]: null,
    [Symbol(kTrailersCount)]: 0,
    [Symbol(RequestTimeout)]: undefined
  }
}
(λ: main) RequestId: 8ef4d650-7c2f-4c57-ba0b-9504e0160346  Duration: 3.44 ms  Billed Duration: 4 ms

ログ内の

%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A

をデコードすると、「あいうえお」になる

また、ログ内の以下ではGETをデコード済である

query: { a: 'あいうえお' },

なお、以下のようにURLエンコードしないと文字化けします

curl -X "GET"  http://localhost:3000/dev/cats/?a=あいうえお
  • 文字化け時のconsole.logの結果を一部抜粋
    url: '/cats?a=%C3%A3%C2%81%C2%82%C3%A3%C2%81%C2%84%C3%A3%C2%81%C2%86%C3%A3%C2%81%C2%88%C3%A3%C2%81%C2%8A',
    method: 'GET',
    originalUrl: '/cats?a=%C3%A3%C2%81%C2%82%C3%A3%C2%81%C2%84%C3%A3%C2%81%C2%86%C3%A3%C2%81%C2%88%C3%A3%C2%81%C2%8A',

URLエンコードされたと仮定の想定箇所では

a=%C3%A3%C2%81%C2%82%C3%A3%C2%81%C2%84%C3%A3%C2%81%C2%86%C3%A3%C2%81%C2%88%C3%A3%C2%81%C2%8A

となっており、デコードすると以下のように文字化けしてますね・・・

あいうえお

ちょっと寄り道

REST API

  • 上記で Get,Postについて記載したが、あくまでもHTTPメソッドに対しての指定方法の説明で、REST APIではない

  • Web API 全般

    • ざっくりクライアントとサーバのやりとり
    • Web上に公開されていて、外部から呼び出して利用が可能なAPI、SOAPとREST
    • URIの考え方がオレオレもある
      • /User/create
      • /User/update
      • /User/delete
      • /CreateUser
      • /UpdateUser
      • /DeleteUser
  • REST APIは

    • リソース、リソースの参照、リソース操作が統一されている
    • 各リソースに対してGET, POST, PUT, DELETEでリクエストを送信し、レスポンスをXMLやjsonなどで受け取る
    • RESTの原則(大きく4つ)に従って実装されているシステムのことを、RESTfulと呼びます。
    • Getメソッド データ取得
    • POSTメソッド データ作成
    • PUTメソッド データ更新
    • DELETEメソッド データ削除
    • /usersの場合を例にすると
      • /users のGet ユーザー一覧
      • /users のPost ユーザー作成
      • /users のPut ユーザー更新
      • /users のDelete ユーザーさくっと
  • GraphQLだとエンドポイント1つで、複数メソッドのような動きなのでRESTとは別なので混同しないようにする

  • 例えば、GraphQLの AWS AppSync の定義 schema.graphql が以下で、エンドポイント1つで操作はクエリーとして提供する。例 https://gist.github.com/ssugimoto/83acb96bce057043bc80c7c43fe7c2a0

schema.graphqls

type Query {
    getNode: [Note]
}

type Mutation {
    addNote(id: ID!, name: String, description: String, image: String): Note
}


type Note @model {
  id: ID!
  name: String!
  description: String
  image: String
}
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?