0

I have a route something like this:

    // collection GET
    fastify.route({
        method: 'GET',
        url: `${constants.EXTERNAL_PATH}/:serviceName/:collectionName/account/:accountId`,
        schema: {
            description: 'Get all documents from the specified table for the specified service database and account.',
            summary: 'Get all documents from the specified table.',
            tags: ['persistence'],
            headers: {
                $ref: 'authorization-user#'
            },
            params:{
                type: 'object',
                properties: {
                    serviceName:    { type: 'string' },
                    collectionName: { type: 'string' },
                    accountId:      { type: 'string' }
                },
                required: ['serviceName', 'collectionName', 'accountId'],
            },
            response: {
                200: {
                    properties: {
                        'documents': {
                            description: 'All the retrieved documents from the specified table for the specified service database and account.',
                            type: 'array',
                            items: {
                                $ref: 'persistence-response-doc#',                  
                            }
                        },
                    },
                },
                '4xx': {
                    $ref: 'error-response#',
                    description: 'Error response'
                }
            }
        },
        handler: async (request, reply) => {
           // Logic goes here //
        }
    });

Now my expectation was that:

This should work:

http://localhost:9011/persistence/external/myservice/mycollection/account/my_actn_id
As it has the service as myservice, collection as mycollection and accountId as my_actn_id

However this should fail with a route error (say when I am missing the :accountId, which is required):

http://localhost:9011/persistence/external/myservice/mycollection/account/  <== should fail

However both are passing, returning same collection results.

What am I missing here?

Thanks, Pradip

Pradip
  • 509
  • 1
  • 5
  • 22
  • Without the accountId you have a different route i.e. to ${constants.EXTERNAL_PATH}/:serviceName/:collectionName/account/ – Frazer Jul 15 '21 at 07:32
  • I see. So does it means the last part of the route I can not say like :params_id? So if I would have something like: ${constants.EXTERNAL_PATH}/:serviceName/:collectionName/account/:accountId/something Where 'something' is just a fixed string, would that work? Thanks. – Pradip Jul 15 '21 at 07:41
  • 1
    You are mixing the validation rules with the routing ones. The validation doesn't happen if the router did not found the route. In fact, if a piece of the URL is missing, the router will reply 404 and not 400 – Manuel Spigolon Jul 15 '21 at 07:50
  • Ok. Does it mean the params validation we should not put in schema section of the route? If so - what is the best place/practice to put the params validation vs the body/response validations? https://www.fastify.io/docs/v2.2.x/Validation-and-Serialization/#validation I was trying to follow actually. – Pradip Jul 15 '21 at 08:12
  • 1
    @Pradip Sorry I don't know the answer to your '/something' question. Perhaps create a route to ${constants.EXTERNAL_PATH}/:serviceName/:collectionName/account/ that returns an error "Account ID missing". – Frazer Jul 15 '21 at 10:41
  • @Frazer: Yeah. I am thinking in same line. Another route for error handling. Then tell me one thing: E.g. I want to have one collection GET and another instance GET. So I can NOT have something like: ${constants.EXTERNAL_PATH}/:serviceName/:collectionName/account/:accountId/:documentId ; where documentId is optional (not present during collection GET, present during instance GET). If I need it, I have two options: 1. One route without :documentId, another with :documentId (instance GET). 2. pass the documentId as query (/?documentId=<>). Which one is REST API best practice? – Pradip Jul 15 '21 at 13:20

1 Answers1

0

Add a minLenght

fastify.route({
        method: 'GET',
        url: `${constants.EXTERNAL_PATH}/:serviceName/:collectionName/account/:accountId`,
        schema: {
            description: 'Get all documents from the specified table for the specified service database and account.',
            summary: 'Get all documents from the specified table.',
            tags: ['persistence'],
            headers: {
                $ref: 'authorization-user#'
            },
            params:{
                type: 'object',
                properties: {
                    serviceName:    { type: 'string', minLength: 1 },
                    collectionName: { type: 'string', minLength: 1 },
                    accountId:      { type: 'string', minLength: 1 }
                },
                required: ['serviceName', 'collectionName', 'accountId'],
            },
            response: {
                200: {
                    properties: {
                        'documents': {
                            description: 'All the retrieved documents from the specified table for the specified service database and account.',
                            type: 'array',
                            items: {
                                $ref: 'persistence-response-doc#',                  
                            }
                        },
                    },
                },
                '4xx': {
                    $ref: 'error-response#',
                    description: 'Error response'
                }
            }
        },
        handler: async (request, reply) => {
           // Logic goes here //
        }
    });