Skip to content

Commit

Permalink
Add noReplace trait
Browse files Browse the repository at this point in the history
Closes #300
  • Loading branch information
mtdowling committed Apr 1, 2020
1 parent 65d6a62 commit 18a3ee4
Show file tree
Hide file tree
Showing 9 changed files with 176 additions and 6 deletions.
81 changes: 79 additions & 2 deletions docs/source/spec/core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1954,6 +1954,17 @@ The following snippet defines the ``PutForecast`` operation.
chanceOfRain: Float
}
The semantics of a ``put`` lifecycle operation are similar to the semantics
of an `HTTP PUT method`_:

The PUT method requests that the state of the target resource be
created or replaced ...

The :ref:`noReplace-trait` can be applied to resources that define a
``put`` lifecycle operation to indicate that a resource cannot be
replaced using the ``put`` operation.


.. _create-lifecycle:

Create lifecycle
Expand All @@ -1966,6 +1977,7 @@ identifiers created by the service.

- Create operations MUST NOT be marked with :ref:`readonly-trait`.
- Create operations MUST form valid :ref:`collection operations <collection-operations>`.
- The ``create`` operation MAY be marked with :ref:`idempotent-trait`.

The following snippet defines the ``CreateForecast`` operation.

Expand All @@ -1988,8 +2000,6 @@ The following snippet defines the ``CreateForecast`` operation.
chanceOfRain: Float,
}
The ``create`` operation MAY be marked with :ref:`idempotent-trait`

.. _read-lifecycle:

Expand Down Expand Up @@ -4578,6 +4588,71 @@ to request additional results from the operation.
Resource traits
===============

.. _noReplace-trait:

``noReplace`` trait
-------------------

Summary
Indicates that the :ref:`put lifecycle <put-lifecycle>` operation of a
resource can only be used to create a resource and cannot replace an
existing resource.
Trait selector
``resource:test(-[put]->)``

*A resource with a put lifecycle operation*
Value type
Annotation trait.

By default, ``put`` lifecycle operations are assumed to both create and
replace an existing resource. Some APIs, however, do not support this
behavior and require that a resource is first deleted before it can be
replaced.

For example, this is the behavior of Amazon DynamoDB's CreateTable_
operation. The "Table" resource identifier, "TableName", is provided by the
client, making it appropriate to model in Smithy as a ``put`` lifecycle
operation. However, ``UpdateTable`` is used to update a table and attempting
to call ``CreateTable`` on a table that already exists will return an error.

.. tabs::

.. code-tab:: smithy

@noReplace
resource Table {
put: CreateTable
}

@idempotent
operation CreateTable {
// ...
}

.. code-tab:: json

{
"smithy": "0.5.0",
"shapes": {
"smithy.example#Table": {
"type": "resource",
"put": {
"target": "smithy.example#CreateTable"
},
"traits": {
"smithy.api#noReplace": true
}
},
"smithy.example#CreateTable": {
"type": "operation",
"traits": {
"smithy.api#idempotent": true
}
}
}
}


.. _references-trait:

``references`` trait
Expand Down Expand Up @@ -6228,3 +6303,5 @@ model:
.. _RFC 3986 Host: https://tools.ietf.org/html/rfc3986#section-3.2.2
.. _CommonMark: https://spec.commonmark.org/
.. _ubiquitous language: https://martinfowler.com/bliki/UbiquitousLanguage.html
.. _CreateTable: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_CreateTable.html
.. _HTTP PUT method: https://tools.ietf.org/html/rfc7231#section-4.3.4
9 changes: 5 additions & 4 deletions docs/themes/smithy/static/default.css_t
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
/* ----- Layout ------ */

html {
font-family: 'Open Sans', sans-serif;
font-family: {{ theme_regular_font }};
background-color: #f7f7f5;
}

/* Base scaffolding taken from Markswatch theme */
body {
color: #24292e;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial,
sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
font-family: {{ theme_regular_font }};
font-size: 18px;
line-height: 1.5;
-ms-text-size-adjust: 100%;
Expand All @@ -35,6 +34,8 @@ blockquote {
margin: 0 2rem 1rem 0;
color: #777;
border-left: 0.5rem solid #eee;
font-family: {{ theme_code_font }};
font-size: 1rem;
}

.width-wrapper {
Expand Down Expand Up @@ -513,7 +514,7 @@ pre {
}

code, pre {
font-family: "SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;
font-family: {{ theme_code_font }};
}

pre a {
Expand Down
2 changes: 2 additions & 0 deletions docs/themes/smithy/theme.conf
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ light_accent = #eee8d5
secondary_background = #382e2e
link_color = #005cc5
toc_column_color = #efebe9
regular_font = -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'
code_font = "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
import software.amazon.smithy.model.traits.JsonNameTrait;
import software.amazon.smithy.model.traits.LengthTrait;
import software.amazon.smithy.model.traits.MediaTypeTrait;
import software.amazon.smithy.model.traits.NoReplaceTrait;
import software.amazon.smithy.model.traits.OptionalAuthTrait;
import software.amazon.smithy.model.traits.PaginatedTrait;
import software.amazon.smithy.model.traits.PatternTrait;
Expand Down Expand Up @@ -169,6 +170,7 @@ public final class Prelude {
IdempotentTrait.ID,
JsonNameTrait.ID,
LengthTrait.ID,
NoReplaceTrait.ID,
MediaTypeTrait.ID,
PaginatedTrait.ID,
PatternTrait.ID,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package software.amazon.smithy.model.traits;

import software.amazon.smithy.model.SourceLocation;
import software.amazon.smithy.model.shapes.ShapeId;

/**
* Indicates that the put lifecycle operation of a resource
* can only be used to create a resource and cannot replace
* an existing resource.
*/
public final class NoReplaceTrait extends BooleanTrait {
public static final ShapeId ID = ShapeId.from("smithy.api#noReplace");

public NoReplaceTrait(SourceLocation sourceLocation) {
super(ID, sourceLocation);
}

public NoReplaceTrait() {
this(SourceLocation.NONE);
}

public static final class Provider extends BooleanTrait.Provider<NoReplaceTrait> {
public Provider() {
super(ID, NoReplaceTrait::new);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ software.amazon.smithy.model.traits.IdRefTrait$Provider
software.amazon.smithy.model.traits.JsonNameTrait$Provider
software.amazon.smithy.model.traits.LengthTrait$Provider
software.amazon.smithy.model.traits.MediaTypeTrait$Provider
software.amazon.smithy.model.traits.NoReplaceTrait$Provider
software.amazon.smithy.model.traits.PaginatedTrait$Provider
software.amazon.smithy.model.traits.PatternTrait$Provider
software.amazon.smithy.model.traits.PrivateTrait$Provider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,12 @@ structure xmlNamespace {
@length(min: 1)
string NonEmptyString

/// Indicates that the put lifecycle operation of a resource
/// can only be used to create a resource and cannot replace
/// an existing resource.
@trait(selector: "resource:test(-[put]->)")
structure noReplace {}

/// Describes the contents of a blob shape using a media type as defined by
/// RFC 6838 (e.g., "video/quicktime").
@trait(selector: ":each(blob, string)")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[ERROR] ns.foo#InvalidResource: Trait `noReplace` cannot be applied to `ns.foo#InvalidResource`. This trait may only be applied to shapes that match the following selector: resource:test(-[put]->) | TraitTarget
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"smithy": "0.5.0",
"shapes": {
"ns.foo#Service": {
"type": "service",
"version": "2019-06-27",
"resources": [
{
"target": "ns.foo#ValidResource"
},
{
"target": "ns.foo#InvalidResource"
}
]
},
"ns.foo#ValidResource": {
"type": "resource",
"put": {
"target": "ns.foo#PutValidResource"
},
"traits": {
"smithy.api#noReplace": true
}
},
"ns.foo#PutValidResource": {
"type": "operation",
"traits": {
"smithy.api#idempotent": true
}
},
"ns.foo#InvalidResource": {
"type": "resource",
"traits": {
"smithy.api#noReplace": true
}
}
}
}

0 comments on commit 18a3ee4

Please sign in to comment.