A small utility package that enables an easy way to guarantee that your API doesn't return fields that you didn't want it to.
yarn add @lcdev/api-fields@0.1
You might want to reduce the duplication when extracting return values. Most of the time, you want to return the same fields for the same entities, records, etc.
API Fields is a decorator for classes that gives you the ability to tie in to @lcdev/mapper
,
specifically its extract
function.
import { ApiField } from '@lcdev/api-fields';
class User extends BaseEntity {
@ApiField()
id: number;
// we never want to give this back in API responses
// maybe it's private, or maybe we don't want consumers to depend on it
firstName: string;
lastName: string;
@ApiField() // works just fine on getters
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
// here, we only want the API Fields of Permission in the nested field
@ApiField(() => Permission)
permission: Permission;
...
}
Under the hood, this creates a listing of the fields you want to expose. We call them "API Fields" because this is usually the way you expose fields in JSON API responses.
We can get that metadata about any given class with the getAPIFields
function.
The object returned can actually be used directly in @lcdev/mapper
.
import { getApiFields } from '@lcdev/api-fields';
import { extract } from '@lcdev/mapper';
// getApiFields can be called anywhere to retrieve the `Extraction` object
const extraction = getApiFields(User);
// use the mapper package to take back only the fields you're interested in
const trimmedFields = extract(fullFields, extraction);
@ApiField() propName
: extractpropName
as-is@ApiField(() => PropertyType) propName
: extract the ApiFields ofPropertyType
aspropName
@ApiField(() => [PropertyType]) propName[]
: map as array, extracting ApiFields of each element@ApiField({ ... }) propName
: extract fields frompropName
(same as@lcdev/mapper
)@ApiField(false) propName
: don't include this field
Renaming a field is supported, in the same way it is in @lcdev/mapper
.
import { ApiField } from '@lcdev/api-fields';
import { rename } from '@lcdev/mapper';
class ImageUpload {
@ApiField(rename('url'))
awsURL: string;
}
When being extracted, the field will be renamed.
Transforming a field is supported, in the same way it is in @lcdev/mapper
.
import { ApiField } from '@lcdev/api-fields';
import { transform } from '@lcdev/mapper';
class ImageUpload {
@ApiField(transform(v => v.replace('https:', '')))
awsURL: string;
}